Add 'projects/hip/' from commit 'e74b05a7bd9454b97dc04d7cc4b66d1fe6c534a7'
git-subtree-dir: projects/hip git-subtree-mainline:64df0940b8git-subtree-split:e74b05a7bd
@@ -0,0 +1,9 @@
|
||||
/_build
|
||||
/_doxygen
|
||||
/_images
|
||||
/_static
|
||||
/_templates
|
||||
/doxygen/html
|
||||
/doxygen/xml
|
||||
/sphinx/_toc.yml
|
||||
__pycache__
|
||||
@@ -0,0 +1,65 @@
|
||||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# This file only contains a selection of the most common options. For a full
|
||||
# list see the documentation:
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
||||
|
||||
import re
|
||||
import sys
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, List
|
||||
|
||||
from rocm_docs import ROCmDocs
|
||||
|
||||
version_numbers = []
|
||||
version_file = open("../VERSION", "r")
|
||||
lines = version_file.readlines()
|
||||
for line in lines:
|
||||
if line[0] == '#':
|
||||
continue
|
||||
version_numbers.append(line.strip())
|
||||
version_number = ".".join(version_numbers)
|
||||
left_nav_title = f"HIP {version_number} Documentation"
|
||||
|
||||
# for PDF output on Read the Docs
|
||||
project = "HIP Documentation"
|
||||
author = "Advanced Micro Devices, Inc."
|
||||
copyright = "Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved."
|
||||
version = version_number
|
||||
release = version_number
|
||||
|
||||
external_toc_path = "./sphinx/_toc.yml"
|
||||
|
||||
docs_core = ROCmDocs(left_nav_title)
|
||||
docs_core.run_doxygen(doxygen_root="doxygen", doxygen_path="doxygen/xml")
|
||||
docs_core.enable_api_reference()
|
||||
docs_core.setup()
|
||||
|
||||
external_projects_current_project = "hip"
|
||||
|
||||
for sphinx_var in ROCmDocs.SPHINX_VARS:
|
||||
globals()[sphinx_var] = getattr(docs_core, sphinx_var)
|
||||
|
||||
# Add the _extensions directory to Python's search path
|
||||
sys.path.append(str(Path(__file__).parent / 'extension'))
|
||||
|
||||
extensions += ["sphinxcontrib.doxylink", "custom_directive"]
|
||||
|
||||
cpp_id_attributes = ["__global__", "__device__", "__host__", "__forceinline__", "static"]
|
||||
cpp_paren_attributes = ["__declspec"]
|
||||
|
||||
suppress_warnings = ["etoc.toctree"]
|
||||
|
||||
numfig = False
|
||||
|
||||
exclude_patterns = [
|
||||
"doxygen/mainpage.md",
|
||||
"understand/glossary.md",
|
||||
'how-to/debugging_env.rst',
|
||||
"data/env_variables_hip.rst"
|
||||
]
|
||||
|
||||
git_url = subprocess.check_output(['git', 'config', '--get', 'remote.origin.url']).strip().decode('ascii')
|
||||
if git_url.find("git:") != -1:
|
||||
html_theme_options = {"repository_url": "https://github.com/ROCm/hip"}
|
||||
@@ -0,0 +1,278 @@
|
||||
.. meta::
|
||||
:description: HIP environment variables
|
||||
:keywords: AMD, HIP, environment variables, environment
|
||||
|
||||
HIP GPU isolation variables
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
The GPU isolation environment variables in HIP are collected in the following table.
|
||||
|
||||
.. _hip-env-isolation:
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 70,30
|
||||
|
||||
* - **Environment variable**
|
||||
- **Value**
|
||||
|
||||
* - | ``ROCR_VISIBLE_DEVICES``
|
||||
| A list of device indices or UUIDs that will be exposed to applications.
|
||||
- Example: ``0,GPU-DEADBEEFDEADBEEF``
|
||||
|
||||
* - | ``GPU_DEVICE_ORDINAL``
|
||||
| Devices indices exposed to OpenCL and HIP applications.
|
||||
- Example: ``0,2``
|
||||
|
||||
* - | ``HIP_VISIBLE_DEVICES`` or ``CUDA_VISIBLE_DEVICES``
|
||||
| Device indices exposed to HIP applications.
|
||||
- Example: ``0,2``
|
||||
|
||||
HIP profiling variables
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
The profiling environment variables in HIP are collected in the following table.
|
||||
|
||||
.. _hip-env-prof:
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 70,30
|
||||
|
||||
* - **Environment variable**
|
||||
- **Value**
|
||||
|
||||
* - | ``HSA_CU_MASK``
|
||||
| Sets the mask on a lower level of queue creation in the driver,
|
||||
| this mask will also be set for queues being profiled.
|
||||
- Example: ``1:0-8``
|
||||
|
||||
* - | ``ROC_GLOBAL_CU_MASK``
|
||||
| Sets the mask on queues created by the HIP or the OpenCL runtimes,
|
||||
| this mask will also be set for queues being profiled.
|
||||
- Example: ``0xf``, enables only 4 CUs
|
||||
|
||||
* - | ``HIP_FORCE_QUEUE_PROFILING``
|
||||
| Used to run the app as if it were run in rocprof. Forces command queue
|
||||
| profiling on by default.
|
||||
- | 0: Disable
|
||||
| 1: Enable
|
||||
|
||||
HIP debug variables
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
The debugging environment variables in HIP are collected in the following table.
|
||||
|
||||
.. _hip-env-debug:
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 35,14,51
|
||||
|
||||
* - **Environment variable**
|
||||
- **Default value**
|
||||
- **Value**
|
||||
|
||||
* - | ``AMD_LOG_LEVEL``
|
||||
| Enables HIP log on various level.
|
||||
- ``0``
|
||||
- | 0: Disable log.
|
||||
| 1: Enables error logs.
|
||||
| 2: Enables warning logs next to lower-level logs.
|
||||
| 3: Enables information logs next to lower-level logs.
|
||||
| 4: Enables debug logs next to lower-level logs.
|
||||
| 5: Enables debug extra logs next to lower-level logs.
|
||||
|
||||
* - | ``AMD_LOG_LEVEL_FILE``
|
||||
| Sets output file for ``AMD_LOG_LEVEL``.
|
||||
- stderr output
|
||||
-
|
||||
|
||||
* - | ``AMD_LOG_MASK``
|
||||
| Specifies HIP log filters. Here is the ` complete list of log masks <https://github.com/ROCm/clr/blob/develop/rocclr/utils/debug.hpp#L40>`_.
|
||||
- ``0x7FFFFFFF``
|
||||
- | 0x1: Log API calls.
|
||||
| 0x2: Kernel and copy commands and barriers.
|
||||
| 0x4: Synchronization and waiting for commands to finish.
|
||||
| 0x8: Decode and display AQL packets.
|
||||
| 0x10: Queue commands and queue contents.
|
||||
| 0x20: Signal creation, allocation, pool.
|
||||
| 0x40: Locks and thread-safety code.
|
||||
| 0x80: Kernel creations and arguments, etc.
|
||||
| 0x100: Copy debug.
|
||||
| 0x200: Detailed copy debug.
|
||||
| 0x400: Resource allocation, performance-impacting events.
|
||||
| 0x800: Initialization and shutdown.
|
||||
| 0x1000: Misc debug, not yet classified.
|
||||
| 0x2000: Show raw bytes of AQL packet.
|
||||
| 0x4000: Show code creation debug.
|
||||
| 0x8000: More detailed command info, including barrier commands.
|
||||
| 0x10000: Log message location.
|
||||
| 0x20000: Memory allocation.
|
||||
| 0x40000: Memory pool allocation, including memory in graphs.
|
||||
| 0x80000: Timestamp details.
|
||||
| 0xFFFFFFFF: Log always even mask flag is zero.
|
||||
|
||||
* - | ``HIP_LAUNCH_BLOCKING``
|
||||
| Used for serialization on kernel execution.
|
||||
- ``0``
|
||||
- | 0: Disable. Kernel executes normally.
|
||||
| 1: Enable. Serializes kernel enqueue, behaves the same as ``AMD_SERIALIZE_KERNEL``.
|
||||
|
||||
* - | ``HIP_VISIBLE_DEVICES`` (or ``CUDA_VISIBLE_DEVICES``)
|
||||
| Only devices whose index is present in the sequence are visible to HIP
|
||||
- Unset by default.
|
||||
- 0,1,2: Depending on the number of devices on the system.
|
||||
|
||||
* - | ``GPU_DUMP_CODE_OBJECT``
|
||||
| Dump code object.
|
||||
- ``0``
|
||||
- | 0: Disable
|
||||
| 1: Enable
|
||||
|
||||
* - | ``AMD_SERIALIZE_KERNEL``
|
||||
| Serialize kernel enqueue.
|
||||
- ``0``
|
||||
- | 0: Disable
|
||||
| 1: Wait for completion before enqueue.
|
||||
| 2: Wait for completion after enqueue.
|
||||
| 3: Both
|
||||
|
||||
* - | ``AMD_SERIALIZE_COPY``
|
||||
| Serialize copies
|
||||
- ``0``
|
||||
- | 0: Disable
|
||||
| 1: Wait for completion before enqueue.
|
||||
| 2: Wait for completion after enqueue.
|
||||
| 3: Both
|
||||
|
||||
* - | ``AMD_DIRECT_DISPATCH``
|
||||
| Enable direct kernel dispatch (Currently for Linux; under development for Windows).
|
||||
- ``1``
|
||||
- | 0: Disable
|
||||
| 1: Enable
|
||||
|
||||
* - | ``GPU_MAX_HW_QUEUES``
|
||||
| The maximum number of hardware queues allocated per device.
|
||||
- ``4``
|
||||
- The variable controls how many independent hardware queues HIP runtime can create per process,
|
||||
per device. If an application allocates more HIP streams than this number, then HIP runtime reuses
|
||||
the same hardware queues for the new streams in a round-robin manner. Note that this maximum
|
||||
number does not apply to hardware queues that are created for CU-masked HIP streams, or
|
||||
cooperative queues for HIP Cooperative Groups (single queue per device).
|
||||
|
||||
HIP memory management related variables
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
The memory management related environment variables in HIP are collected in the
|
||||
following table.
|
||||
|
||||
.. _hip-env-memory:
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 35,14,51
|
||||
|
||||
* - **Environment variable**
|
||||
- **Default value**
|
||||
- **Value**
|
||||
|
||||
* - | ``HIP_HIDDEN_FREE_MEM``
|
||||
| Amount of memory to hide from the free memory reported by hipMemGetInfo.
|
||||
- ``0``
|
||||
- | 0: Disable
|
||||
| Unit: megabyte (MB)
|
||||
|
||||
* - | ``HIP_HOST_COHERENT``
|
||||
| Specifies if the memory is coherent between the host and GPU in ``hipHostMalloc``.
|
||||
- ``0``
|
||||
- | 0: Memory is not coherent.
|
||||
| 1: Memory is coherent.
|
||||
| Environment variable has effect, if the following conditions are statisfied:
|
||||
| - One of the ``hipHostMallocDefault``, ``hipHostMallocPortable``, ``hipHostMallocWriteCombined`` or ``hipHostMallocNumaUser`` flag set to 1.
|
||||
| - ``hipHostMallocCoherent``, ``hipHostMallocNonCoherent`` and ``hipHostMallocMapped`` flags set to 0.
|
||||
|
||||
* - | ``HIP_INITIAL_DM_SIZE``
|
||||
| Set initial heap size for device malloc.
|
||||
- ``8388608``
|
||||
- | Unit: Byte
|
||||
| The default value corresponds to 8 MB.
|
||||
|
||||
* - | ``HIP_MEM_POOL_SUPPORT``
|
||||
| Enables memory pool support in HIP.
|
||||
- ``0``
|
||||
- | 0: Disable
|
||||
| 1: Enable
|
||||
|
||||
* - | ``HIP_MEM_POOL_USE_VM``
|
||||
| Enables memory pool support in HIP.
|
||||
- | ``0``: other OS
|
||||
| ``1``: Windows
|
||||
- | 0: Disable
|
||||
| 1: Enable
|
||||
|
||||
* - | ``HIP_VMEM_MANAGE_SUPPORT``
|
||||
| Virtual Memory Management Support.
|
||||
- ``1``
|
||||
- | 0: Disable
|
||||
| 1: Enable
|
||||
|
||||
* - | ``GPU_MAX_HEAP_SIZE``
|
||||
| Set maximum size of the GPU heap to % of board memory.
|
||||
- ``100``
|
||||
- | Unit: Percentage
|
||||
|
||||
* - | ``GPU_MAX_REMOTE_MEM_SIZE``
|
||||
| Maximum size that allows device memory substitution with system.
|
||||
- ``2``
|
||||
- | Unit: kilobyte (KB)
|
||||
|
||||
* - | ``GPU_NUM_MEM_DEPENDENCY``
|
||||
| Number of memory objects for dependency tracking.
|
||||
- ``256``
|
||||
-
|
||||
|
||||
* - | ``GPU_STREAMOPS_CP_WAIT``
|
||||
| Force the stream memory operation to wait on CP.
|
||||
- ``0``
|
||||
- | 0: Disable
|
||||
| 1: Enable
|
||||
|
||||
* - | ``HSA_LOCAL_MEMORY_ENABLE``
|
||||
| Enable HSA device local memory usage.
|
||||
- ``1``
|
||||
- | 0: Disable
|
||||
| 1: Enable
|
||||
|
||||
* - | ``PAL_ALWAYS_RESIDENT``
|
||||
| Force memory resources to become resident at allocation time.
|
||||
- ``0``
|
||||
- | 0: Disable
|
||||
| 1: Enable
|
||||
|
||||
* - | ``PAL_PREPINNED_MEMORY_SIZE``
|
||||
| Size of prepinned memory.
|
||||
- ``64``
|
||||
- | Unit: kilobyte (KB)
|
||||
|
||||
* - | ``REMOTE_ALLOC``
|
||||
| Use remote memory for the global heap allocation.
|
||||
- ``0``
|
||||
- | 0: Disable
|
||||
| 1: Enable
|
||||
|
||||
HIP miscellaneous variables
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
The following table lists environment variables that are useful but relate to
|
||||
different features in HIP.
|
||||
|
||||
.. _hip-env-other:
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 35,14,51
|
||||
|
||||
* - **Environment variable**
|
||||
- **Default value**
|
||||
- **Value**
|
||||
|
||||
* - | ``HIPRTC_COMPILE_OPTIONS_APPEND``
|
||||
| Sets compile options needed for ``hiprtc`` compilation.
|
||||
- None
|
||||
- ``--gpu-architecture=gfx906:sramecc+:xnack``, ``-fgpu-rdc``
|
||||
@@ -0,0 +1,274 @@
|
||||
<mxfile host="65bd71144e">
|
||||
<diagram id="zBbb_w2fufU70cdOGtND" name="1 oldal">
|
||||
<mxGraphModel dx="1310" dy="1222" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="660" pageHeight="610" background="none" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="5965" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#5E5B61;fontColor=#FFFFFF;strokeColor=none;spacing=0;" parent="1" vertex="1">
|
||||
<mxGeometry y="-190" width="680" height="610" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5966" value="<font face="Helvetica">time</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="380" width="55" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5967" value="" style="endArrow=classic;startArrow=none;html=1;rounded=0;strokeWidth=2;startFill=0;strokeColor=#FFFFFF;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="5966" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="510" y="140" as="sourcePoint"/>
|
||||
<mxPoint x="671" y="396" as="targetPoint"/>
|
||||
<Array as="points">
|
||||
<mxPoint x="190" y="396"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5968" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#333333;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="-130" width="660" height="70" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5969" value="<font face="Helvetica">default stream</font>" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="-110" width="121" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5970" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="200" y="-120" width="50" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5971" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#4f1623;fontColor=#FFFFFF;strokeColor=none;" parent="5970" vertex="1">
|
||||
<mxGeometry width="50.000000000000014" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5972" value="<div>H2D<br><font style="font-size: 12px;">data1</font></div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="5970" vertex="1">
|
||||
<mxGeometry x="0.8964285714285714" y="8.75" width="48.21071428571429" height="27.5" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5973" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="250" y="-120" width="50" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5974" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#4f1623;fontColor=#FFFFFF;strokeColor=none;" parent="5973" vertex="1">
|
||||
<mxGeometry width="50.000000000000014" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5975" value="<div>H2D<br><font style="font-size: 12px;">data2</font></div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="5973" vertex="1">
|
||||
<mxGeometry x="0.8964285714285714" y="8.75" width="48.21071428571429" height="27.5" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5976" value="" style="endArrow=none;html=1;rounded=0;fillColor=#eeeeee;strokeColor=#808080;entryX=0;entryY=1;entryDx=0;entryDy=0;exitX=0;exitY=0;exitDx=0;exitDy=0;" parent="5973" source="5974" target="5974" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="-0.6900000000002251" y="260" as="sourcePoint"/>
|
||||
<mxPoint x="-0.6899999999999977" y="105" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5977" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="300" y="-120" width="120" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5978" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=#A20025;" parent="5977" vertex="1">
|
||||
<mxGeometry width="120.00000000000001" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5979" value="<div>kernel<br><font style="font-size: 12px;">data1</font></div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="5977" vertex="1">
|
||||
<mxGeometry x="4.485465996156356" y="7.499999999999999" width="109.1463392398047" height="29.999999999999996" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5980" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="420" y="-120" width="120" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5981" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=#A20025;" parent="5980" vertex="1">
|
||||
<mxGeometry width="120.00000000000001" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5982" value="<div>kernel<br><font style="font-size: 12px;">data2</font></div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="5980" vertex="1">
|
||||
<mxGeometry x="4.485465996156356" y="7.499999999999999" width="109.1463392398047" height="29.999999999999996" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5983" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="540" y="-120" width="50" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5984" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#4f1623;fontColor=#FFFFFF;strokeColor=none;" parent="5983" vertex="1">
|
||||
<mxGeometry width="50.000000000000014" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5985" value="<div>D2H<br><font style="font-size: 12px;">data1</font></div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="5983" vertex="1">
|
||||
<mxGeometry x="0.8964285714285714" y="8.75" width="48.21071428571429" height="27.5" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5986" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="590" y="-120" width="50" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5987" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#4f1623;fontColor=#FFFFFF;strokeColor=none;" parent="5986" vertex="1">
|
||||
<mxGeometry width="50.000000000000014" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5988" value="<div>D2H<br><font style="font-size: 12px;">data2</font></div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="5986" vertex="1">
|
||||
<mxGeometry x="0.8964285714285714" y="8.75" width="48.21071428571429" height="27.5" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5989" value="" style="endArrow=none;html=1;rounded=0;fillColor=#eeeeee;strokeColor=#808080;entryX=0;entryY=1;entryDx=0;entryDy=0;exitX=0;exitY=0;exitDx=0;exitDy=0;" parent="5986" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="0.8999999999999773" as="sourcePoint"/>
|
||||
<mxPoint x="0.8999999999999773" y="45" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5990" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#333333;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="75" width="660" height="70" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5991" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="250" y="87.5" width="50" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5992" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#4f1623;fontColor=#FFFFFF;strokeColor=none;" parent="5991" vertex="1">
|
||||
<mxGeometry width="50.000000000000014" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5993" value="<div>H2D<br><font style="font-size: 12px;">data2</font></div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="5991" vertex="1">
|
||||
<mxGeometry x="0.8964285714285714" y="8.75" width="48.21071428571429" height="27.5" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5994" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="370" y="87.5" width="120" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5995" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=#A20025;" parent="5994" vertex="1">
|
||||
<mxGeometry width="120.00000000000001" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5996" value="<div>kernel<br><font style="font-size: 12px;">data2</font></div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="5994" vertex="1">
|
||||
<mxGeometry x="4.485465996156356" y="7.499999999999999" width="109.1463392398047" height="29.999999999999996" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5997" value="<font face="Helvetica">stream2</font>" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="95" width="120" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5998" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="490" y="87.5" width="50" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5999" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#4f1623;fontColor=#FFFFFF;strokeColor=none;" parent="5998" vertex="1">
|
||||
<mxGeometry width="50.000000000000014" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6000" value="<div>D2H<br><font style="font-size: 12px;">data2</font></div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="5998" vertex="1">
|
||||
<mxGeometry x="0.8964285714285714" y="8.75" width="48.21071428571429" height="27.5" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6001" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#333333;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="-10" width="660" height="70" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6002" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="200" y="2.5" width="50" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6003" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#4f1623;fontColor=#FFFFFF;strokeColor=none;" parent="6002" vertex="1">
|
||||
<mxGeometry width="50.000000000000014" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6004" value="<div>H2D<br><font style="font-size: 12px;">data1</font></div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="6002" vertex="1">
|
||||
<mxGeometry x="0.8964285714285714" y="8.75" width="48.21071428571429" height="27.5" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6005" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="250" y="2.5" width="120" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6006" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=#A20025;" parent="6005" vertex="1">
|
||||
<mxGeometry width="120.00000000000001" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6007" value="<div>kernel<br><font style="font-size: 12px;">data1</font></div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="6005" vertex="1">
|
||||
<mxGeometry x="4.485465996156356" y="7.499999999999999" width="109.1463392398047" height="29.999999999999996" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6008" value="<font face="Helvetica">stream1</font>" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="10" width="120" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6009" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="370" y="2.5" width="50" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6010" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#4f1623;fontColor=#FFFFFF;strokeColor=none;" parent="6009" vertex="1">
|
||||
<mxGeometry width="50.000000000000014" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6011" value="<div>D2H<br><font style="font-size: 12px;">data1</font></div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="6009" vertex="1">
|
||||
<mxGeometry x="0.8964285714285714" y="8.75" width="48.21071428571429" height="27.5" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6014" value="" style="endArrow=none;html=1;rounded=0;fillColor=#eeeeee;strokeColor=#808080;entryX=0;entryY=0;entryDx=0;entryDy=0;exitX=0;exitY=1;exitDx=0;exitDy=0;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="249.99999999999955" y="144.99999999999977" as="sourcePoint"/>
|
||||
<mxPoint x="250" y="-10.000000000000227" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="6015" value="" style="endArrow=none;html=1;rounded=0;fillColor=#eeeeee;strokeColor=#808080;entryX=0;entryY=0;entryDx=0;entryDy=0;exitX=0;exitY=1;exitDx=0;exitDy=0;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="370" y="144.99999999999977" as="sourcePoint"/>
|
||||
<mxPoint x="370" y="-10.000000000000227" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="6016" value="<font face="Helvetica">Seqeuntial calls:</font>" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="-170" width="170" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6017" value="<font face="Helvetica">Asynchronous calls:</font>" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="-50" width="170" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6018" value="<font face="Helvetica">Asynchronous calls with hipEvent:<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="11" y="160" width="300" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6019" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#333333;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="11" y="290" width="660" height="70" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6020" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="251" y="302.5" width="50" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6021" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#4f1623;fontColor=#FFFFFF;strokeColor=none;" parent="6020" vertex="1">
|
||||
<mxGeometry width="50.000000000000014" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6022" value="<div>H2D<br><font style="font-size: 12px;">data2</font></div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="6020" vertex="1">
|
||||
<mxGeometry x="0.8964285714285714" y="8.75" width="48.21071428571429" height="27.5" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6023" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="371" y="302.5" width="120" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6024" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=#A20025;" parent="6023" vertex="1">
|
||||
<mxGeometry width="120.00000000000001" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6025" value="<div>kernel<br><font style="font-size: 12px;">data2</font></div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="6023" vertex="1">
|
||||
<mxGeometry x="4.485465996156356" y="7.499999999999999" width="109.1463392398047" height="29.999999999999996" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6026" value="<font face="Helvetica">stream2</font>" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="21" y="310" width="120" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6027" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#333333;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="11" y="205" width="660" height="70" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6028" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="201" y="217.5" width="50" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6029" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#4f1623;fontColor=#FFFFFF;strokeColor=none;" parent="6028" vertex="1">
|
||||
<mxGeometry width="50.000000000000014" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6030" value="<div>H2D<br><font style="font-size: 12px;">data1</font></div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="6028" vertex="1">
|
||||
<mxGeometry x="0.8964285714285714" y="8.75" width="48.21071428571429" height="27.5" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6031" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="251" y="217.5" width="120" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6032" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=#A20025;" parent="6031" vertex="1">
|
||||
<mxGeometry width="120.00000000000001" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6033" value="<div>kernel<br><font style="font-size: 12px;">data1</font></div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="6031" vertex="1">
|
||||
<mxGeometry x="4.485465996156356" y="7.499999999999999" width="109.1463392398047" height="29.999999999999996" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6034" value="<font face="Helvetica">stream1</font>" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="21" y="225" width="120" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6035" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="491" y="302.5" width="50" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6036" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#4f1623;fontColor=#FFFFFF;strokeColor=none;" parent="6035" vertex="1">
|
||||
<mxGeometry width="50.000000000000014" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6037" value="<div>D2H<br><font style="font-size: 12px;">data2</font></div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="6035" vertex="1">
|
||||
<mxGeometry x="0.8964285714285714" y="8.75" width="48.21071428571429" height="27.5" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6040" value="" style="endArrow=none;html=1;rounded=0;fillColor=#eeeeee;strokeColor=#808080;entryX=0;entryY=0;entryDx=0;entryDy=0;exitX=0;exitY=1;exitDx=0;exitDy=0;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="250.30999999999972" y="359.9999999999998" as="sourcePoint"/>
|
||||
<mxPoint x="250.30999999999983" y="204.99999999999977" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="6041" value="<font style="font-size: 12px;" face="Helvetica">event</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="341" y="175" width="55" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6043" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="372" y="217.5" width="50" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6044" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#4f1623;fontColor=#FFFFFF;strokeColor=none;" parent="6043" vertex="1">
|
||||
<mxGeometry x="-1" width="50.000000000000014" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6045" value="<div>D2H<br><font style="font-size: 12px;">data1</font></div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="6043" vertex="1">
|
||||
<mxGeometry x="0.8964285714285714" y="8.75" width="48.21071428571429" height="27.5" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6047" value="" style="endArrow=none;html=1;rounded=0;fillColor=#eeeeee;strokeColor=#FF0000;entryX=1;entryY=0;entryDx=0;entryDy=0;exitX=1;exitY=1;exitDx=0;exitDy=0;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="370.9999999999998" y="359.9999999999998" as="sourcePoint"/>
|
||||
<mxPoint x="371" y="204.99999999999977" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="6051" value="" style="endArrow=none;html=1;rounded=0;fillColor=#eeeeee;strokeColor=#FF0000;entryX=1;entryY=0;entryDx=0;entryDy=0;exitX=1;exitY=1;exitDx=0;exitDy=0;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="540.9999999999998" y="359.9999999999998" as="sourcePoint"/>
|
||||
<mxPoint x="541" y="204.99999999999977" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="6052" value="<font style="font-size: 12px;" face="Helvetica">eventA<br>eventB<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="511" y="160" width="55" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
После Ширина: | Высота: | Размер: 33 KiB |
@@ -0,0 +1,904 @@
|
||||
<mxfile host="65bd71144e">
|
||||
<diagram id="zBbb_w2fufU70cdOGtND" name="1 oldal">
|
||||
<mxGraphModel dx="757" dy="937" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1200" pageHeight="1600" background="none" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="5818" value="" style="rounded=0;fillColor=#5E5B61;fontColor=#FFFFFF;strokeColor=none;spacing=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="20" y="90" width="640" height="450" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5400" value="" style="rounded=0;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;spacing=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="30" y="120" width="620" height="200" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5401" value="Block" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="310" y="120" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5402" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#A20025;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="360" y="160" width="280" height="140" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5403" value="<font face="Klavika" style="font-size: 17px;">Thread-block tile</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="420" y="160" width="160" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5404" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="390" y="210" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5405" value="Warp" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="405" y="210" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5406" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="399.8600000000001" y="236.5" as="sourcePoint"/>
|
||||
<mxPoint x="399.8600000000001" y="283.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5407" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="409.8600000000001" y="236.5" as="sourcePoint"/>
|
||||
<mxPoint x="409.8600000000001" y="283.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5408" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="419.8600000000001" y="236.5" as="sourcePoint"/>
|
||||
<mxPoint x="419.8600000000001" y="283.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5409" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="429.8600000000001" y="236.5" as="sourcePoint"/>
|
||||
<mxPoint x="429.8600000000001" y="283.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5410" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="439.8600000000001" y="236.5" as="sourcePoint"/>
|
||||
<mxPoint x="439.8600000000001" y="283.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5411" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="449.8600000000001" y="236.5" as="sourcePoint"/>
|
||||
<mxPoint x="449.8600000000001" y="283.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5412" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="459.8600000000001" y="236.5" as="sourcePoint"/>
|
||||
<mxPoint x="459.8600000000001" y="283.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5413" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="469.8600000000001" y="236.5" as="sourcePoint"/>
|
||||
<mxPoint x="469.8600000000001" y="283.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5414" value="" style="group;fontColor=#FFFFFF;" vertex="1" connectable="0" parent="1">
|
||||
<mxGeometry x="380" y="200" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5415" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#523E43;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="5414">
|
||||
<mxGeometry width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5416" value="Warp" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#FFFFFF;" vertex="1" parent="5414">
|
||||
<mxGeometry x="15" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5417" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5414">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="9.86" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="9.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5418" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5414">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="19.860000000000113" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="19.860000000000113" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5419" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5414">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="29.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="29.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5420" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5414">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="39.86000000000011" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="39.86000000000011" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5421" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5414">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="49.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="49.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5422" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5414">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="59.86000000000011" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="59.86000000000011" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5423" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5414">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="69.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="69.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5424" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5414">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="79.86000000000013" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="79.86000000000013" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5425" value="" style="group;fontColor=#FFFFFF;" vertex="1" connectable="0" parent="1">
|
||||
<mxGeometry x="370" y="190" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5426" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#585556;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="5425">
|
||||
<mxGeometry width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5427" value="Warp" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="5425">
|
||||
<mxGeometry x="15" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5428" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5425">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="9.86" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="9.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5429" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5425">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="19.860000000000113" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="19.860000000000113" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5430" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5425">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="29.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="29.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5431" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5425">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="39.86000000000011" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="39.86000000000011" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5432" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5425">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="49.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="49.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5433" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5425">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="59.86000000000011" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="59.86000000000011" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5434" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5425">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="69.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="69.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5435" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5425">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="79.86000000000013" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="79.86000000000013" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5436" value="" style="group;fontColor=#FFFFFF;" vertex="1" connectable="0" parent="1">
|
||||
<mxGeometry x="540" y="210" width="100" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5437" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="5436">
|
||||
<mxGeometry width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5438" value="Warp" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#FFFFFF;" vertex="1" parent="5436">
|
||||
<mxGeometry x="15" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5439" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5436">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="9.86" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="9.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5440" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5436">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="19.860000000000113" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="19.860000000000113" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5441" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5436">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="29.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="29.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5442" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5436">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="39.86000000000011" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="39.86000000000011" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5443" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5436">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="49.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="49.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5444" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5436">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="59.86000000000011" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="59.86000000000011" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5445" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5436">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="69.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="69.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5446" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5436">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="79.86000000000013" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="79.86000000000013" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5447" value="" style="group;fontColor=#FFFFFF;" vertex="1" connectable="0" parent="1">
|
||||
<mxGeometry x="530" y="200" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5448" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#523E43;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="5447">
|
||||
<mxGeometry width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5449" value="Warp" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#FFFFFF;" vertex="1" parent="5447">
|
||||
<mxGeometry x="15" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5450" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5447">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="9.86" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="9.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5451" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5447">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="19.860000000000113" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="19.860000000000113" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5452" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5447">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="29.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="29.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5453" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5447">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="39.86000000000011" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="39.86000000000011" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5454" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5447">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="49.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="49.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5455" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5447">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="59.86000000000011" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="59.86000000000011" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5456" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5447">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="69.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="69.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5457" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5447">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="79.86000000000013" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="79.86000000000013" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5458" value="" style="group;fontColor=#FFFFFF;" vertex="1" connectable="0" parent="1">
|
||||
<mxGeometry x="520" y="190" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5459" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#585556;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="5458">
|
||||
<mxGeometry width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5460" value="Warp" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="5458">
|
||||
<mxGeometry x="15" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5461" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5458">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="9.86" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="9.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5462" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5458">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="19.860000000000113" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="19.860000000000113" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5463" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5458">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="29.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="29.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5464" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5458">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="39.86000000000011" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="39.86000000000011" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5465" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5458">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="49.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="49.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5466" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5458">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="59.86000000000011" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="59.86000000000011" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5467" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5458">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="69.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="69.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5468" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5458">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="79.86000000000013" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="79.86000000000013" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5469" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#A20025;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="40" y="160" width="280" height="140" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5470" value="<font face="Klavika" style="font-size: 17px;">Thread-block tile</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="100" y="160" width="160" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5471" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="70" y="210" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5472" value="Warp" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="85" y="210" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5473" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="79.86000000000001" y="236.5" as="sourcePoint"/>
|
||||
<mxPoint x="79.86000000000001" y="283.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5474" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="89.86000000000013" y="236.5" as="sourcePoint"/>
|
||||
<mxPoint x="89.86000000000013" y="283.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5475" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="99.86000000000001" y="236.5" as="sourcePoint"/>
|
||||
<mxPoint x="99.86000000000001" y="283.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5476" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="109.86000000000013" y="236.5" as="sourcePoint"/>
|
||||
<mxPoint x="109.86000000000013" y="283.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5477" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="119.86000000000001" y="236.5" as="sourcePoint"/>
|
||||
<mxPoint x="119.86000000000001" y="283.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5478" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="129.86000000000013" y="236.5" as="sourcePoint"/>
|
||||
<mxPoint x="129.86000000000013" y="283.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5479" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="139.86" y="236.5" as="sourcePoint"/>
|
||||
<mxPoint x="139.86" y="283.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5480" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="149.86000000000013" y="236.5" as="sourcePoint"/>
|
||||
<mxPoint x="149.86000000000013" y="283.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5481" value="" style="group;fontColor=#FFFFFF;" vertex="1" connectable="0" parent="1">
|
||||
<mxGeometry x="60" y="200" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5482" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#523E43;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="5481">
|
||||
<mxGeometry width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5483" value="Warp" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#FFFFFF;" vertex="1" parent="5481">
|
||||
<mxGeometry x="15" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5484" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5481">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="9.86" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="9.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5485" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5481">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="19.860000000000113" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="19.860000000000113" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5486" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5481">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="29.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="29.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5487" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5481">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="39.86000000000011" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="39.86000000000011" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5488" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5481">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="49.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="49.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5489" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5481">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="59.86000000000011" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="59.86000000000011" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5490" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5481">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="69.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="69.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5491" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5481">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="79.86000000000013" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="79.86000000000013" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5492" value="" style="group;fontColor=#FFFFFF;" vertex="1" connectable="0" parent="1">
|
||||
<mxGeometry x="50" y="190" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5493" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#585556;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="5492">
|
||||
<mxGeometry width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5494" value="Warp" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="5492">
|
||||
<mxGeometry x="15" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5495" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5492">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="9.86" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="9.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5496" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5492">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="19.860000000000113" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="19.860000000000113" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5497" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5492">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="29.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="29.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5498" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5492">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="39.86000000000011" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="39.86000000000011" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5499" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5492">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="49.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="49.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5500" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5492">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="59.86000000000011" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="59.86000000000011" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5501" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5492">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="69.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="69.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5502" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5492">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="79.86000000000013" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="79.86000000000013" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5503" value="" style="group;fontColor=#FFFFFF;" vertex="1" connectable="0" parent="1">
|
||||
<mxGeometry x="220" y="210" width="100" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5504" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="5503">
|
||||
<mxGeometry width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5505" value="Warp" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#FFFFFF;" vertex="1" parent="5503">
|
||||
<mxGeometry x="15" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5506" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5503">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="9.86" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="9.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5507" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5503">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="19.860000000000113" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="19.860000000000113" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5508" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5503">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="29.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="29.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5509" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5503">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="39.86000000000011" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="39.86000000000011" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5510" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5503">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="49.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="49.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5511" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5503">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="59.86000000000011" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="59.86000000000011" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5512" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5503">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="69.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="69.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5513" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5503">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="79.86000000000013" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="79.86000000000013" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5514" value="" style="group;fontColor=#FFFFFF;" vertex="1" connectable="0" parent="1">
|
||||
<mxGeometry x="210" y="200" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5515" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#523E43;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="5514">
|
||||
<mxGeometry width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5516" value="Warp" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#FFFFFF;" vertex="1" parent="5514">
|
||||
<mxGeometry x="15" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5517" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5514">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="9.86" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="9.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5518" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5514">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="19.860000000000113" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="19.860000000000113" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5519" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5514">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="29.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="29.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5520" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5514">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="39.86000000000011" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="39.86000000000011" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5521" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5514">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="49.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="49.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5522" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5514">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="59.86000000000011" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="59.86000000000011" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5523" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5514">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="69.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="69.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5524" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5514">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="79.86000000000013" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="79.86000000000013" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5525" value="" style="group;fontColor=#FFFFFF;" vertex="1" connectable="0" parent="1">
|
||||
<mxGeometry x="200" y="190" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5526" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#585556;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="5525">
|
||||
<mxGeometry width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5527" value="Warp" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="5525">
|
||||
<mxGeometry x="15" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5528" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5525">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="9.86" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="9.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5529" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5525">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="19.860000000000113" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="19.860000000000113" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5530" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5525">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="29.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="29.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5531" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5525">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="39.86000000000011" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="39.86000000000011" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5532" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5525">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="49.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="49.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5533" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5525">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="59.86000000000011" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="59.86000000000011" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5534" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5525">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="69.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="69.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5535" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5525">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="79.86000000000013" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="79.86000000000013" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5536" value="" style="rounded=0;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;spacing=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="30" y="340" width="620" height="180" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5537" value="Block" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="310" y="340" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5538" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#A20025;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="370" y="380" width="260" height="120" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5539" value="<font face="Klavika">Coalesced group</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="420" y="380" width="160" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5541" value="Warp" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="405" y="430" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5561" value="" style="group;fontColor=#FFFFFF;" vertex="1" connectable="0" parent="1">
|
||||
<mxGeometry x="380" y="410" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5562" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#585556;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="5561">
|
||||
<mxGeometry width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5563" value="Warp" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="5561">
|
||||
<mxGeometry x="15" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5564" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5561">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="9.86" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="9.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5565" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5561">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="19.860000000000113" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="19.860000000000113" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5567" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5561">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="39.86000000000011" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="39.86000000000011" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5568" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5561">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="49.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="49.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5569" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5561">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="59.86000000000011" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="59.86000000000011" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5570" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5561">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="69.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="69.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5594" value="" style="group;fontColor=#FFFFFF;" vertex="1" connectable="0" parent="1">
|
||||
<mxGeometry x="530" y="410" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5595" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#585556;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="5594">
|
||||
<mxGeometry width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5596" value="Warp" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="5594">
|
||||
<mxGeometry x="15" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5597" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5594">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="9.86" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="9.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5598" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5594">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="19.860000000000113" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="19.860000000000113" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5599" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5594">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="29.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="29.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5600" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5594">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="39.86000000000011" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="39.86000000000011" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5602" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5594">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="59.86000000000011" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="59.86000000000011" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5603" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5594">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="69.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="69.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5604" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5594">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="79.86000000000013" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="79.86000000000013" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5605" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#A20025;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="40" y="380" width="260" height="120" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5606" value="<font face="Klavika">Coalesced group</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="100" y="380" width="160" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5608" value="Warp" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="85" y="430" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5628" value="" style="group;fontColor=#FFFFFF;" vertex="1" connectable="0" parent="1">
|
||||
<mxGeometry x="50" y="410" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5629" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#585556;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="5628">
|
||||
<mxGeometry width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5630" value="Warp" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="5628">
|
||||
<mxGeometry x="15" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5631" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5628">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="9.86" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="9.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5633" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5628">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="29.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="29.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5634" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5628">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="39.86000000000011" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="39.86000000000011" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5635" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5628">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="49.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="49.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5637" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5628">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="69.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="69.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5661" value="" style="group;fontColor=#FFFFFF;" vertex="1" connectable="0" parent="1">
|
||||
<mxGeometry x="200" y="410" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5662" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#585556;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="5661">
|
||||
<mxGeometry width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5663" value="Warp" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="5661">
|
||||
<mxGeometry x="15" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5664" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5661">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="9.86" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="9.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5666" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5661">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="29.86" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="29.86" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5667" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5661">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="39.86000000000011" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="39.86000000000011" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5669" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" edge="1" parent="5661">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="59.86000000000011" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="59.86000000000011" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5819" value="Grid" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="310" y="90" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
После Ширина: | Высота: | Размер: 64 KiB |
|
После Ширина: | Высота: | Размер: 308 KiB |
@@ -0,0 +1,76 @@
|
||||
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0" version="24.7.7">
|
||||
<diagram id="zBbb_w2fufU70cdOGtND" name="1 oldal">
|
||||
<mxGraphModel dx="1114" dy="694" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1200" pageHeight="1600" background="none" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="5536" value="" style="rounded=0;fillColor=#5e5b61;fontColor=#FFFFFF;strokeColor=none;spacing=0;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="340" y="10" width="280" height="520" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1Txoek2s6jAQB3cqoh21-5821" value="" style="rounded=0;fillColor=#5e5b61;fontColor=#FFFFFF;strokeColor=none;spacing=0;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="10" width="280" height="520" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="5401" value="Stream 1" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Segoe UI;fontSize=18;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry y="10" width="320" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1Txoek2s6jAQB3cqoh21-5820" value="Kernel B" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#c13555;fontColor=#FFFFFF;strokeColor=none;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="30" y="170" width="240" height="100" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1Txoek2s6jAQB3cqoh21-5819" value="Stream 2" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Segoe UI;fontSize=18;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="320" y="10" width="320" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1Txoek2s6jAQB3cqoh21-5822" value="Kernel A" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#c13555;fontColor=#FFFFFF;strokeColor=none;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="30" y="50" width="240" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1Txoek2s6jAQB3cqoh21-5825" value="hipDeviceSynchronize" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#c13555;fontColor=#FFFFFF;strokeColor=none;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="30" y="330" width="570" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1Txoek2s6jAQB3cqoh21-5826" value="Kernel C" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#c13555;fontColor=#FFFFFF;strokeColor=none;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="360" y="170" width="240" height="150" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1Txoek2s6jAQB3cqoh21-5827" value="hipDeviceSynchronize" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#c13555;fontColor=#FFFFFF;strokeColor=none;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="30" y="120" width="570" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1Txoek2s6jAQB3cqoh21-5828" value="Kernel D" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#c13555;fontColor=#FFFFFF;strokeColor=none;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="30" y="380" width="240" height="140" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="xSuKLjqbr4XYnemY5Hsx-5818" value="<font style="font-size: 18px;" color="#ffffff"><font style="font-size: 18px;">Kernel A</font><br style="font-size: 18px;"></font>" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#c13555;strokeColor=default;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="840" y="10" width="120" height="120" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="xSuKLjqbr4XYnemY5Hsx-5819" value="<font style="font-size: 18px;" color="#ffffff"><font style="font-size: 18px;">Kernel B</font><br style="font-size: 18px;"></font>" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#c13555;strokeColor=default;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="680" y="210" width="120" height="120" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="xSuKLjqbr4XYnemY5Hsx-5820" value="<font style="font-size: 18px;" color="#ffffff"><font style="font-size: 18px;">Kernel C</font><br style="font-size: 18px;"></font>" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#c13555;strokeColor=default;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="1000" y="210" width="120" height="120" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="xSuKLjqbr4XYnemY5Hsx-5821" value="<div style="font-size: 18px;"><font style="font-size: 18px;" color="#ffffff"><font style="font-size: 18px;">Kernel D</font></font></div>" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#c13555;strokeColor=default;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="840" y="410" width="120" height="120" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="xSuKLjqbr4XYnemY5Hsx-5822" value="" style="endArrow=blockThin;html=1;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=0;exitX=1;exitY=1;exitDx=0;exitDy=0;strokeWidth=5;endFill=1;fontFamily=Segoe UI;fontSize=18;" parent="1" source="xSuKLjqbr4XYnemY5Hsx-5818" target="xSuKLjqbr4XYnemY5Hsx-5820" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="990" y="230" as="sourcePoint" />
|
||||
<mxPoint x="1060" y="190" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="xSuKLjqbr4XYnemY5Hsx-5823" value="" style="endArrow=blockThin;html=1;rounded=0;entryX=1;entryY=0;entryDx=0;entryDy=0;exitX=0;exitY=1;exitDx=0;exitDy=0;strokeWidth=5;endFill=1;fontFamily=Segoe UI;fontSize=18;" parent="1" source="xSuKLjqbr4XYnemY5Hsx-5818" target="xSuKLjqbr4XYnemY5Hsx-5819" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="952" y="122" as="sourcePoint" />
|
||||
<mxPoint x="1028" y="198" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="xSuKLjqbr4XYnemY5Hsx-5824" value="" style="endArrow=blockThin;html=1;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=0;exitX=1;exitY=1;exitDx=0;exitDy=0;strokeWidth=5;endFill=1;fontFamily=Segoe UI;fontSize=18;" parent="1" source="xSuKLjqbr4XYnemY5Hsx-5819" target="xSuKLjqbr4XYnemY5Hsx-5821" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="868" y="162" as="sourcePoint" />
|
||||
<mxPoint x="792" y="238" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="xSuKLjqbr4XYnemY5Hsx-5825" value="" style="endArrow=blockThin;html=1;rounded=0;strokeWidth=5;endFill=1;entryX=1;entryY=0;entryDx=0;entryDy=0;exitX=0;exitY=1;exitDx=0;exitDy=0;fontFamily=Segoe UI;fontSize=18;" parent="1" source="xSuKLjqbr4XYnemY5Hsx-5820" target="xSuKLjqbr4XYnemY5Hsx-5821" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1088.57" y="370" as="sourcePoint" />
|
||||
<mxPoint x="1000" y="420" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
После Ширина: | Высота: | Размер: 25 KiB |
@@ -0,0 +1,162 @@
|
||||
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0" version="24.7.13">
|
||||
<diagram id="zBbb_w2fufU70cdOGtND" name="1 oldal">
|
||||
<mxGraphModel dx="1114" dy="646" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1200" pageHeight="1600" background="none" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="5818" value="" style="rounded=0;fillColor=#5E5B61;fontColor=#FFFFFF;strokeColor=none;spacing=0;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry width="1130" height="460" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="5401" value="Streams" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;rounded=0;fontFamily=Segoe UI;fontSize=18;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="10" width="100" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1Txoek2s6jAQB3cqoh21-5822" value="<font style="font-size: 18px;">kernel A</font>" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#c23555;fontColor=#FFFFFF;strokeColor=default;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="390" y="130" width="90" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1Txoek2s6jAQB3cqoh21-5827" value="kernel launch A" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#A20025;fontColor=#FFFFFF;strokeColor=default;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="70" width="190" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5819" value="<div style="font-size: 18px;"><font style="font-size: 18px;">kernel B</font></div>" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#c23555;fontColor=#FFFFFF;strokeColor=default;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="580" y="130" width="70" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5820" value="kernel C" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#c23555;fontColor=#FFFFFF;strokeColor=default;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="770" y="130" width="90" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5822" value="kernel launch B" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#A20025;fontColor=#FFFFFF;strokeColor=default;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="390" y="70" width="190" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5823" value="kernel launch C" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#A20025;fontColor=#FFFFFF;strokeColor=default;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="580" y="70" width="190" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5824" value="host activity" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#A20025;fontColor=#FFFFFF;strokeColor=none;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="30" y="70" width="120" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5826" value="device activity" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#c23555;fontColor=#FFFFFF;strokeColor=none;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="30" y="130" width="120" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5827" value="" style="endArrow=blockThin;startArrow=blockThin;html=1;rounded=0;endFill=1;startFill=1;strokeWidth=3;fontFamily=Segoe UI;fontSize=18;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="480" y="210" as="sourcePoint" />
|
||||
<mxPoint x="580" y="210" as="targetPoint" />
|
||||
<Array as="points" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5829" value="" style="endArrow=blockThin;startArrow=blockThin;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;endFill=1;startFill=1;strokeWidth=3;fontFamily=Segoe UI;fontSize=18;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="650" y="210" as="sourcePoint" />
|
||||
<mxPoint x="770" y="210" as="targetPoint" />
|
||||
<Array as="points" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5832" value="" style="endArrow=blockThin;startArrow=none;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;endFill=1;startFill=0;strokeWidth=3;entryX=0;entryY=0.75;entryDx=0;entryDy=0;fontFamily=Segoe UI;fontSize=18;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="200" y="270" as="sourcePoint" />
|
||||
<mxPoint x="1100" y="270" as="targetPoint" />
|
||||
<Array as="points" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5834" value="time" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;fontColor=#FFFFFF;strokeColor=none;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="1050" y="270" width="70" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5835" value="" style="endArrow=none;dashed=1;html=1;rounded=0;exitX=1;exitY=1;exitDx=0;exitDy=0;strokeWidth=3;fontFamily=Segoe UI;fontSize=18;" parent="1" source="1Txoek2s6jAQB3cqoh21-5822" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="420" y="360" as="sourcePoint" />
|
||||
<mxPoint x="480" y="210" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5836" value="" style="endArrow=none;dashed=1;html=1;rounded=0;exitX=1;exitY=1;exitDx=0;exitDy=0;strokeWidth=3;fontFamily=Segoe UI;fontSize=18;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="580" y="170" as="sourcePoint" />
|
||||
<mxPoint x="580" y="210" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5837" value="" style="endArrow=none;dashed=1;html=1;rounded=0;exitX=1;exitY=1;exitDx=0;exitDy=0;strokeWidth=3;fontFamily=Segoe UI;fontSize=18;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="650" y="170" as="sourcePoint" />
|
||||
<mxPoint x="650" y="210" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5838" value="" style="endArrow=none;dashed=1;html=1;rounded=0;exitX=1;exitY=1;exitDx=0;exitDy=0;strokeWidth=3;fontFamily=Segoe UI;fontSize=18;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="770" y="170" as="sourcePoint" />
|
||||
<mxPoint x="770" y="210" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5839" value="kernel launch D" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#A20025;fontColor=#FFFFFF;strokeColor=default;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="770" y="70" width="180" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5840" value="kernel D" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#c23555;fontColor=#FFFFFF;strokeColor=default;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="950" y="130" width="90" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5841" value="" style="endArrow=blockThin;startArrow=blockThin;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;endFill=1;startFill=1;strokeWidth=3;fontFamily=Segoe UI;fontSize=18;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="860" y="210" as="sourcePoint" />
|
||||
<mxPoint x="950" y="210" as="targetPoint" />
|
||||
<Array as="points" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5842" value="" style="endArrow=none;dashed=1;html=1;rounded=0;exitX=1;exitY=1;exitDx=0;exitDy=0;strokeWidth=3;fontFamily=Segoe UI;fontSize=18;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="859" y="170" as="sourcePoint" />
|
||||
<mxPoint x="859" y="210" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5843" value="" style="endArrow=none;dashed=1;html=1;rounded=0;exitX=1;exitY=1;exitDx=0;exitDy=0;strokeWidth=3;fontFamily=Segoe UI;fontSize=18;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="949" y="170" as="sourcePoint" />
|
||||
<mxPoint x="949" y="210" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5844" value="device idling due to kernel launch congestion" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;fontColor=#FFFFFF;strokeColor=none;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="480" y="220" width="390" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5845" value="kernel A" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#c23555;fontColor=#FFFFFF;strokeColor=default;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="530" y="370" width="90" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5847" value="<div style="font-size: 18px;">kernel B</div>" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#c23555;fontColor=#FFFFFF;strokeColor=default;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="620" y="370" width="70" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5848" value="kernel C" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#c23555;fontColor=#FFFFFF;strokeColor=default;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="690" y="370" width="90" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5849" value="graph launch" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#A20025;fontColor=#FFFFFF;strokeColor=default;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="310" width="330" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5851" value="host activity" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#A20025;fontColor=#FFFFFF;strokeColor=none;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="30" y="310" width="120" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5852" value="device activity" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#c23555;fontColor=#FFFFFF;strokeColor=none;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="30" y="370" width="120" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5860" value="kernel D" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#c23555;fontColor=#FFFFFF;strokeColor=default;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="780" y="370" width="90" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5861" value="" style="endArrow=blockThin;startArrow=blockThin;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;endFill=1;startFill=1;strokeWidth=3;fontFamily=Segoe UI;fontSize=18;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="870" y="450" as="sourcePoint" />
|
||||
<mxPoint x="1040" y="450" as="targetPoint" />
|
||||
<Array as="points" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5862" value="" style="endArrow=none;dashed=1;html=1;rounded=0;exitX=1;exitY=1;exitDx=0;exitDy=0;strokeWidth=3;fontFamily=Segoe UI;fontSize=18;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="870" y="410" as="sourcePoint" />
|
||||
<mxPoint x="870" y="450" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5863" value="" style="endArrow=none;dashed=1;html=1;rounded=0;exitX=1;exitY=1;exitDx=0;exitDy=0;strokeWidth=3;fontFamily=Segoe UI;fontSize=18;" parent="1" source="TYkUcg6durY7-jI84bFK-5840" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="960" y="410" as="sourcePoint" />
|
||||
<mxPoint x="1040" y="450" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="TYkUcg6durY7-jI84bFK-5864" value="Graph" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;rounded=0;fontFamily=Segoe UI;fontSize=18;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="270" width="100" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="mD1MZE_vsaNfBI7xCEMp-5818" value="speedup" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;fontColor=#FFFFFF;strokeColor=none;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="880" y="400" width="140" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
После Ширина: | Высота: | Размер: 203 KiB |
@@ -0,0 +1,106 @@
|
||||
<mxfile host="65bd71144e">
|
||||
<diagram id="zBbb_w2fufU70cdOGtND" name="1 oldal">
|
||||
<mxGraphModel dx="1547" dy="1302" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="660" pageHeight="610" background="none" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="5927" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#5E5B61;fontColor=#FFFFFF;strokeColor=none;spacing=0;" parent="1" vertex="1">
|
||||
<mxGeometry y="-10" width="740" height="290" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5928" value="Pageable data transfer" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Helvetica;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" width="340" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5955" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#4F1623;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="160" width="340" height="100" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5959" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="230" y="170" width="120" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5960" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" parent="UvHuP5o6jSuoLTm0AUZA-5959" vertex="1">
|
||||
<mxGeometry width="120" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5961" value="<div>Pinned memory</div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="UvHuP5o6jSuoLTm0AUZA-5959" vertex="1">
|
||||
<mxGeometry width="120" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="LV0FwBpydXXZrUbya0PG-5946" value="Pinned data transfer" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Helvetica;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="380" width="340" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5952" value="" style="group;fillColor=#9C2A44;" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="70" y="170" width="120" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5950" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#9C2A44;fontColor=#FFFFFF;strokeColor=none;" parent="UvHuP5o6jSuoLTm0AUZA-5952" vertex="1">
|
||||
<mxGeometry width="120" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5951" value="Pageable memory" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="UvHuP5o6jSuoLTm0AUZA-5952" vertex="1">
|
||||
<mxGeometry width="120" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="LV0FwBpydXXZrUbya0PG-5974" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;strokeWidth=2;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" parent="1" target="UvHuP5o6jSuoLTm0AUZA-5950" edge="1" source="UvHuP5o6jSuoLTm0AUZA-5961">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="220" y="250" as="sourcePoint"/>
|
||||
<mxPoint x="109.5" y="201" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5929" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#4F1623;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="20" y="40" width="340" height="100" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5930" value="" style="group" vertex="1" connectable="0" parent="1">
|
||||
<mxGeometry x="230" y="50" width="120" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5931" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="5930">
|
||||
<mxGeometry width="120" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5932" value="<div>Device memory</div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="5930">
|
||||
<mxGeometry width="120" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="LV0FwBpydXXZrUbya0PG-5968" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeWidth=2;strokeColor=#ffffff;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="5932" target="UvHuP5o6jSuoLTm0AUZA-5960" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="290" y="120" as="sourcePoint"/>
|
||||
<mxPoint x="289.5" y="160" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5944" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#4F1623;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="380" y="160" width="340" height="100" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5945" value="" style="group" vertex="1" connectable="0" parent="1">
|
||||
<mxGeometry x="590" y="170" width="120" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5946" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="5945">
|
||||
<mxGeometry width="120" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5947" value="<div>Pinned memory</div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="5945">
|
||||
<mxGeometry width="120" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5948" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#4F1623;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="380" y="40" width="340" height="100" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5949" value="" style="group" vertex="1" connectable="0" parent="1">
|
||||
<mxGeometry x="590" y="50" width="120" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5950" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="5949">
|
||||
<mxGeometry width="120" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5951" value="<div>Device memory</div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="5949">
|
||||
<mxGeometry width="120" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5952" style="edgeStyle=none;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;startArrow=classic;startFill=1;strokeWidth=2;strokeColor=#FFFFFF;" edge="1" parent="1" source="5947" target="5951">
|
||||
<mxGeometry relative="1" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5958" value="<div>Host</div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;direction=west;" vertex="1" parent="1">
|
||||
<mxGeometry x="20" y="195" width="50" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5960" value="<div>Device</div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="20" y="75" width="70" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5961" value="<div>Device</div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="380" y="75" width="70" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5962" value="<div>Host</div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="380" y="195" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5964" value="" style="edgeStyle=none;html=1;strokeWidth=2;startArrow=classic;startFill=1;strokeColor=#FFFFFF;" edge="1" parent="1" source="UvHuP5o6jSuoLTm0AUZA-5951" target="UvHuP5o6jSuoLTm0AUZA-5961">
|
||||
<mxGeometry relative="1" as="geometry"/>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
После Ширина: | Высота: | Размер: 13 KiB |
|
После Ширина: | Высота: | Размер: 1.1 KiB |
|
После Ширина: | Высота: | Размер: 1.1 KiB |
|
После Ширина: | Высота: | Размер: 2.9 KiB |
|
После Ширина: | Высота: | Размер: 1.1 KiB |
|
После Ширина: | Высота: | Размер: 1.3 KiB |
|
После Ширина: | Высота: | Размер: 401 B |
|
После Ширина: | Высота: | Размер: 1.1 KiB |
|
После Ширина: | Высота: | Размер: 83 KiB |
@@ -0,0 +1,127 @@
|
||||
<mxfile host="65bd71144e">
|
||||
<diagram id="zBbb_w2fufU70cdOGtND" name="1 oldal">
|
||||
<mxGraphModel dx="1584" dy="1200" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="660" pageHeight="610" background="none" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="5927" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#5E5B61;fontColor=#FFFFFF;strokeColor=none;spacing=0;" parent="1" vertex="1">
|
||||
<mxGeometry y="-30" width="680" height="380" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5945" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=#A20025;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="-10" width="660" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5946" value="<font face="Helvetica">HIP Runtime API</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="75" y="-10" width="530" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5953" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="10" y="80" width="330" height="260" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5925" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#333333;fontColor=#FFFFFF;strokeColor=none;" parent="UvHuP5o6jSuoLTm0AUZA-5953" vertex="1">
|
||||
<mxGeometry width="330" height="260" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5952" value="" style="group" parent="UvHuP5o6jSuoLTm0AUZA-5953" vertex="1" connectable="0">
|
||||
<mxGeometry x="16.67" y="190.00279999999998" width="293.33" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5950" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#60a917;fontColor=#ffffff;strokeColor=#2D7600;" parent="UvHuP5o6jSuoLTm0AUZA-5952" vertex="1">
|
||||
<mxGeometry width="293.33000000000004" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5951" value="<div>CUDA Driver API</div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="UvHuP5o6jSuoLTm0AUZA-5952" vertex="1">
|
||||
<mxGeometry x="10.9643478387712" y="7.500000000000001" width="266.79913074343256" height="30.000000000000004" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5948" value="" style="endArrow=classic;startArrow=none;html=1;rounded=0;strokeWidth=2;startFill=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.358;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;strokeColor=#FFFFFF;" parent="UvHuP5o6jSuoLTm0AUZA-5953" source="5967" target="UvHuP5o6jSuoLTm0AUZA-5950" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="103.33500000000004" y="108.22000000000003" as="sourcePoint"/>
|
||||
<mxPoint x="85" y="145.6" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5966" value="" style="group" parent="UvHuP5o6jSuoLTm0AUZA-5953" vertex="1" connectable="0">
|
||||
<mxGeometry x="16.670000000000016" y="64" width="210" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5967" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#60a917;fontColor=#ffffff;strokeColor=#2D7600;" parent="5966" vertex="1">
|
||||
<mxGeometry width="210.00000000000003" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5968" value="<div>CUDA runtime</div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="5966" vertex="1">
|
||||
<mxGeometry x="9.499565493273565" y="7.499999999999974" width="191.0060936696582" height="29.999999999999996" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5982" value="" style="endArrow=classic;startArrow=none;html=1;rounded=0;strokeWidth=2;startFill=0;strokeColor=#FFFFFF;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="270" y="60" as="sourcePoint"/>
|
||||
<mxPoint x="270" y="270" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5955" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#333333;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="350" y="80" width="320" height="260" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5955" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="360" y="270" width="140" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5956" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=#A20025;" parent="5955" vertex="1">
|
||||
<mxGeometry width="140.00000000000003" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5957" value="<div>ROCr runtime</div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="5955" vertex="1">
|
||||
<mxGeometry x="2.51" y="8.75" width="134.99" height="27.5" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5958" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="520" y="270" width="140" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5959" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=#A20025;" parent="5958" vertex="1">
|
||||
<mxGeometry width="140.00000000000003" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5960" value="<div>PAL</div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="5958" vertex="1">
|
||||
<mxGeometry x="5.233043662182416" y="7.499999999999999" width="127.33739577977217" height="29.999999999999996" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5962" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="405" y="144.91" width="210" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5963" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=#A20025;" parent="5962" vertex="1">
|
||||
<mxGeometry width="210.00000000000003" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5964" value="<div>CLR</div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="5962" vertex="1">
|
||||
<mxGeometry x="7.849565493273624" y="7.499999999999999" width="191.0060936696582" height="29.999999999999996" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5965" value="" style="endArrow=classic;startArrow=none;html=1;rounded=0;strokeWidth=2;startFill=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#FFFFFF;exitX=0.823;exitY=1.047;exitDx=0;exitDy=0;exitPerimeter=0;" parent="1" target="5963" edge="1" source="5946">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="510" y="60" as="sourcePoint"/>
|
||||
<mxPoint x="640" y="290" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5969" value="" style="endArrow=classic;startArrow=none;html=1;rounded=0;strokeWidth=2;startFill=0;strokeColor=#FFFFFF;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="570" y="190" as="sourcePoint"/>
|
||||
<mxPoint x="570" y="270" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5971" value="" style="endArrow=classic;startArrow=none;html=1;rounded=0;strokeWidth=2;startFill=0;strokeColor=#FFFFFF;entryX=0.661;entryY=0.007;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" target="5956" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="453" y="190" as="sourcePoint"/>
|
||||
<mxPoint x="450" y="270" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5981" value="" style="endArrow=classic;startArrow=none;html=1;rounded=0;strokeWidth=2;startFill=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#FFFFFF;" parent="1" target="5967" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="132" y="60" as="sourcePoint"/>
|
||||
<mxPoint x="95" y="140" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5957" value="<font face="Helvetica"><span style="background-color: rgb(77, 77, 77);">AMD Platform</span><br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="440" y="84" width="140" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5926" value="<font style="background-color: rgb(77, 77, 77);">NVIDIA Platform</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="80" width="330" height="34.0392" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5973" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=#A20025;" vertex="1" parent="1">
|
||||
<mxGeometry x="10" y="40" width="330" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5975" value="<font face="Helvetica">hipother</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="10" y="40" width="330" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5976" value="" style="endArrow=classic;startArrow=none;html=1;rounded=0;strokeWidth=2;startFill=0;strokeColor=#FFFFFF;exitX=0.823;exitY=1.047;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="175.59000000000003" y="20.00000000000008" as="sourcePoint"/>
|
||||
<mxPoint x="176" y="40" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
После Ширина: | Высота: | Размер: 14 KiB |
@@ -0,0 +1,46 @@
|
||||
<mxfile host="65bd71144e">
|
||||
<diagram id="zBbb_w2fufU70cdOGtND" name="1 oldal">
|
||||
<mxGraphModel dx="438" dy="902" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1200" pageHeight="1600" background="none" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="5536" value="" style="rounded=0;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;spacing=0;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="340" y="10" width="280" height="540" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="1Txoek2s6jAQB3cqoh21-5821" value="" style="rounded=0;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;spacing=0;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="10" width="280" height="540" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5401" value="Stream 1" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Segoe UI;fontSize=18;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry y="10" width="320" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="1Txoek2s6jAQB3cqoh21-5820" value="Kernel A" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#A20025;fontColor=#FFFFFF;strokeColor=none;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="30" y="130" width="240" height="100" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="1Txoek2s6jAQB3cqoh21-5819" value="Stream 2" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Segoe UI;fontSize=18;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="320" y="10" width="320" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="1Txoek2s6jAQB3cqoh21-5822" value="Memory Copy" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#A20025;fontColor=#FFFFFF;strokeColor=none;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="30" y="50" width="240" height="60" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="1Txoek2s6jAQB3cqoh21-5825" value="hipDeviceSynchronize" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#A20025;fontColor=#FFFFFF;strokeColor=none;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="30" y="410" width="570" height="40" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="1Txoek2s6jAQB3cqoh21-5826" value="Kernel B" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#A20025;fontColor=#FFFFFF;strokeColor=none;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="360" y="130" width="240" height="150" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="1Txoek2s6jAQB3cqoh21-5828" value="Kernel C" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#A20025;fontColor=#FFFFFF;strokeColor=none;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="30" y="250" width="240" height="140" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5537" value="Memory Copy" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#A20025;fontColor=#FFFFFF;strokeColor=none;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="360" y="50" width="240" height="60" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5538" value="Memory Copy" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#A20025;fontColor=#FFFFFF;strokeColor=none;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="30" y="470" width="240" height="60" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5539" value="Memory Copy" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#A20025;fontColor=#FFFFFF;strokeColor=none;fontFamily=Segoe UI;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="360" y="470" width="240" height="60" as="geometry"/>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
После Ширина: | Высота: | Размер: 9.8 KiB |
@@ -0,0 +1,448 @@
|
||||
<mxfile host="65bd71144e">
|
||||
<diagram id="zBbb_w2fufU70cdOGtND" name="1 oldal">
|
||||
<mxGraphModel dx="1054" dy="1139" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="660" pageHeight="610" background="none" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#5E5B61;fontColor=#FFFFFF;strokeColor=none;spacing=0;" parent="1" vertex="1">
|
||||
<mxGeometry width="480" height="690" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="3" value="Bank conflict free reduction" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="210" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="30" width="380" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6" value="<font face="Klavika" style="font-size: 17px;">Shared</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="190" y="30" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="142" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="147" value="5" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="27.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="305" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="142" target="339" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="450" y="50" as="sourcePoint"/>
|
||||
<mxPoint x="450" y="360" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="315" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="65" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="316" value="13" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="72.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="339" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#4F1623;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="180" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="340" value="0" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="27.5" y="190" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="342" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="110" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="343" value="8" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="117.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="344" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="315" target="347" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="540" y="50" as="sourcePoint"/>
|
||||
<mxPoint x="540" y="360" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="345" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="155" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="346" value="2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="162.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="347" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#4F1623;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="65" y="180" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="348" value="1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="72.5" y="190" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="350" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="351" value="7" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="207.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="352" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="342" target="355" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="630" y="50" as="sourcePoint"/>
|
||||
<mxPoint x="630" y="360" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="353" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="245" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="354" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="252.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="355" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#4F1623;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="110" y="180" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="356" value="2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="117.5" y="190" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="358" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="290" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="359" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="297.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="360" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" target="363" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="175" y="110" as="sourcePoint"/>
|
||||
<mxPoint x="720" y="360" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="361" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="335" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="362" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="342.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="363" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#4F1623;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="155" y="180" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="364" value="3" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="162.5" y="190" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="366" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="240" width="380" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="367" value="<font face="Klavika" style="font-size: 17px;">Shared</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="190" y="240" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="368" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="270" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="369" value="7" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="27.5" y="280" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="371" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="65" y="270" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="372" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="72.5" y="280" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="376" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="110" y="270" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="377" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="117.5" y="280" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="379" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="155" y="270" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="380" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="162.5" y="280" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="384" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="270" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="385" value="7" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="207.5" y="280" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="387" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="245" y="270" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="388" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="252.5" y="280" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="392" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="290" y="270" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="393" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="297.5" y="280" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="395" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="335" y="270" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="396" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="342.5" y="280" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="400" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="339" target="368" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="50" y="110" as="sourcePoint"/>
|
||||
<mxPoint x="50" y="130" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="401" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="347" target="371" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="50" y="180" as="sourcePoint"/>
|
||||
<mxPoint x="50" y="220" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="402" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="355" target="376" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="60" y="190" as="sourcePoint"/>
|
||||
<mxPoint x="60" y="230" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="403" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="363" target="379" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="70" y="200" as="sourcePoint"/>
|
||||
<mxPoint x="70" y="240" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="451" value="" style="edgeStyle=segmentEdgeStyle;endArrow=classic;html=1;curved=0;rounded=1;endSize=8;startSize=8;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#FFFFFF;fontColor=#FFFFFF;dashed=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="350" target="339" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="140" y="310" as="sourcePoint"/>
|
||||
<mxPoint x="70" y="355" as="targetPoint"/>
|
||||
<Array as="points">
|
||||
<mxPoint x="220" y="130"/>
|
||||
<mxPoint x="40" y="130"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="452" value="" style="edgeStyle=segmentEdgeStyle;endArrow=classic;html=1;curved=0;rounded=1;endSize=8;startSize=8;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#FFFFFF;fontColor=#FFFFFF;dashed=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="353" target="347" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="230" y="120" as="sourcePoint"/>
|
||||
<mxPoint x="50" y="170" as="targetPoint"/>
|
||||
<Array as="points">
|
||||
<mxPoint x="265" y="140"/>
|
||||
<mxPoint x="85" y="140"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="453" value="" style="edgeStyle=segmentEdgeStyle;endArrow=classic;html=1;curved=0;rounded=1;endSize=8;startSize=8;strokeColor=#FFFFFF;fontColor=#FFFFFF;dashed=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="358" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="275" y="120" as="sourcePoint"/>
|
||||
<mxPoint x="130" y="180" as="targetPoint"/>
|
||||
<Array as="points">
|
||||
<mxPoint x="310" y="150"/>
|
||||
<mxPoint x="130" y="150"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="454" value="" style="edgeStyle=segmentEdgeStyle;endArrow=classic;html=1;curved=0;rounded=1;endSize=8;startSize=8;strokeColor=#FFFFFF;fontColor=#FFFFFF;dashed=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="361" target="363" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="320" y="120" as="sourcePoint"/>
|
||||
<mxPoint x="140" y="200" as="targetPoint"/>
|
||||
<Array as="points">
|
||||
<mxPoint x="355" y="160"/>
|
||||
<mxPoint x="175" y="160"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="481" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#4F1623;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="370" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="482" value="0" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="27.5" y="380" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="483" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#4F1623;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="65" y="370" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="484" value="1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="72.5" y="380" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="489" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="430" width="380" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="490" value="<font face="Klavika" style="font-size: 17px;">Shared</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="190" y="430" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="491" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="460" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="492" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="27.5" y="470" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="493" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="65" y="460" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="494" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="72.5" y="470" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="495" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="110" y="460" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="496" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="117.5" y="470" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="497" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="155" y="460" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="498" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="162.5" y="470" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="499" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="460" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="500" value="7" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="207.5" y="470" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="501" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="245" y="460" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="502" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="252.5" y="470" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="503" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="290" y="460" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="504" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="297.5" y="470" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="505" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="335" y="460" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="506" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="342.5" y="470" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="507" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="481" target="491" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="50" y="300" as="sourcePoint"/>
|
||||
<mxPoint x="50" y="320" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="508" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="483" target="493" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="50" y="370" as="sourcePoint"/>
|
||||
<mxPoint x="50" y="410" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="511" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="368" target="481" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="50" y="240" as="sourcePoint"/>
|
||||
<mxPoint x="50" y="280" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="512" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="371" target="483" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="60" y="250" as="sourcePoint"/>
|
||||
<mxPoint x="60" y="290" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="513" value="" style="edgeStyle=segmentEdgeStyle;endArrow=classic;html=1;curved=0;rounded=1;endSize=8;startSize=8;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#FFFFFF;fontColor=#FFFFFF;dashed=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="376" target="481" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="230" y="120" as="sourcePoint"/>
|
||||
<mxPoint x="50" y="190" as="targetPoint"/>
|
||||
<Array as="points">
|
||||
<mxPoint x="130" y="340"/>
|
||||
<mxPoint x="40" y="340"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="514" value="" style="edgeStyle=segmentEdgeStyle;endArrow=classic;html=1;curved=0;rounded=1;endSize=8;startSize=8;strokeColor=#FFFFFF;fontColor=#FFFFFF;dashed=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="379" target="483" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="140" y="330" as="sourcePoint"/>
|
||||
<mxPoint x="80" y="370" as="targetPoint"/>
|
||||
<Array as="points">
|
||||
<mxPoint x="175" y="350"/>
|
||||
<mxPoint x="85" y="350"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="516" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#4F1623;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="530" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="517" value="0" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="27.5" y="540" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="520" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="590" width="380" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="521" value="<font face="Klavika" style="font-size: 17px;">Shared</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="190" y="590" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="522" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="620" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="523" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="27.5" y="630" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="524" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="65" y="620" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="525" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="72.5" y="630" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="526" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="110" y="620" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="527" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="117.5" y="630" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="528" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="155" y="620" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="529" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="162.5" y="630" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="530" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="620" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="531" value="7" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="207.5" y="630" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="532" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="245" y="620" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="533" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="252.5" y="630" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="534" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="290" y="620" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="535" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="297.5" y="630" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="536" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="335" y="620" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="537" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="342.5" y="630" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="538" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="516" target="522" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="50" y="460" as="sourcePoint"/>
|
||||
<mxPoint x="50" y="480" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="540" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="491" target="516" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="50" y="430" as="sourcePoint"/>
|
||||
<mxPoint x="50" y="470" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="541" value="" style="edgeStyle=segmentEdgeStyle;endArrow=classic;html=1;curved=0;rounded=1;endSize=8;startSize=8;strokeColor=#FFFFFF;fontColor=#FFFFFF;dashed=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="493" target="516" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="185" y="330" as="sourcePoint"/>
|
||||
<mxPoint x="95" y="380" as="targetPoint"/>
|
||||
<Array as="points">
|
||||
<mxPoint x="85" y="555"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="542" value="Thread IDs" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;whiteSpace=wrap;rotation=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="400" y="170" width="62.5" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="543" value="Data snapshot" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;whiteSpace=wrap;rotation=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="400" y="50" width="62.5" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="544" value="Thread IDs" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;whiteSpace=wrap;rotation=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="400" y="370" width="62.5" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="545" value="Data snapshot" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;whiteSpace=wrap;rotation=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="400" y="260" width="62.5" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="546" value="Thread IDs" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;whiteSpace=wrap;rotation=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="400" y="540" width="62.5" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="547" value="Data snapshot" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;whiteSpace=wrap;rotation=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="400" y="450" width="62.5" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="548" value="Data snapshot" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;whiteSpace=wrap;rotation=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="400" y="610" width="62.5" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
После Ширина: | Высота: | Размер: 61 KiB |
@@ -0,0 +1,142 @@
|
||||
<mxfile host="65bd71144e">
|
||||
<diagram id="zBbb_w2fufU70cdOGtND" name="1 oldal">
|
||||
<mxGraphModel dx="992" dy="899" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="660" pageHeight="610" background="none" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#5E5B61;fontColor=#FFFFFF;strokeColor=none;spacing=0;" parent="1" vertex="1">
|
||||
<mxGeometry width="480" height="680" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="3" value="Fold-left" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="210" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="130" y="30" width="330" height="120" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6" value="<font face="Klavika" style="font-size: 17px;">Input</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="265" y="30" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="107" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="360" y="60" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="141" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="250" y="60" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="143" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#523E43;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="160" width="220" height="120" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="142" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="140" y="60" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="145" value="8" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="375" y="85" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="146" value="13" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="265" y="85" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="147" value="5" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="155" y="85" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="284" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="30" y="190" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="285" value="z" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="45" y="215" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="288" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="140" y="190" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="289" value="5" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="155" y="215" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="290" value="<font face="Klavika" style="font-size: 17px;">f(z,5)</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="100" y="160" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="291" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="142" target="288" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="184.5" y="140" as="sourcePoint"/>
|
||||
<mxPoint x="185" y="180" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="292" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#523E43;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="130" y="290" width="220" height="120" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="293" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="140" y="320" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="294" value="5" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="155" y="345" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="295" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="250" y="320" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="296" value="13" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="265" y="345" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="297" value="<font face="Klavika" style="font-size: 17px;">f(f(z,5),13)</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="210" y="290" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="298" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="141" target="295" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="194.5" y="150" as="sourcePoint"/>
|
||||
<mxPoint x="195" y="200" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="299" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#523E43;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="240" y="420" width="220" height="120" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="300" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="250" y="450" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="301" value="13" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="265" y="475" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="302" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="360" y="450" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="303" value="8" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="375" y="475" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="304" value="<font face="Klavika" style="font-size: 17px;">f(f(f(z,5),13),8)<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="320" y="420" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="305" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="107" target="302" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="305" y="150" as="sourcePoint"/>
|
||||
<mxPoint x="305" y="330" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="306" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="143" target="293" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="195" y="150" as="sourcePoint"/>
|
||||
<mxPoint x="195" y="200" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="308" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="292" target="300" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="140" y="290" as="sourcePoint"/>
|
||||
<mxPoint x="195" y="330" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="310" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="345" y="550" width="120" height="120" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="311" value="<font face="Klavika" style="font-size: 17px;">Result</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="375" y="550" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="312" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="360" y="580" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="313" value="13" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="375" y="605" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="314" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0;entryY=0;entryDx=0;entryDy=0;" parent="1" target="312" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="350" y="540" as="sourcePoint"/>
|
||||
<mxPoint x="305" y="460" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
После Ширина: | Высота: | Размер: 20 KiB |
@@ -0,0 +1,442 @@
|
||||
<mxfile host="65bd71144e">
|
||||
<diagram id="zBbb_w2fufU70cdOGtND" name="1 oldal">
|
||||
<mxGraphModel dx="1054" dy="1139" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="660" pageHeight="610" background="none" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#5E5B61;fontColor=#FFFFFF;strokeColor=none;spacing=0;" parent="1" vertex="1">
|
||||
<mxGeometry width="480" height="610" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="3" value="Naive Shared Reduction" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="210" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="30" width="380" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6" value="<font face="Klavika" style="font-size: 17px;">Shared</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="145" y="30" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="142" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="147" value="5" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="27.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="305" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="142" target="339" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="450" y="50" as="sourcePoint"/>
|
||||
<mxPoint x="450" y="360" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="315" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="65" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="316" value="13" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="72.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="339" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#4F1623;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="130" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="340" value="0" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="27.5" y="140" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="341" value="" style="edgeStyle=segmentEdgeStyle;endArrow=classic;html=1;curved=0;rounded=1;endSize=8;startSize=8;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#FFFFFF;fontColor=#FFFFFF;dashed=1;" parent="1" source="315" target="339" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="270" y="260" as="sourcePoint"/>
|
||||
<mxPoint x="320" y="210" as="targetPoint"/>
|
||||
<Array as="points">
|
||||
<mxPoint x="85" y="155"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="342" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="110" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="343" value="8" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="117.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="344" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="342" target="347" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="540" y="50" as="sourcePoint"/>
|
||||
<mxPoint x="540" y="360" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="345" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="155" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="346" value="2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="162.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="347" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#4F1623;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="110" y="130" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="348" value="2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="117.5" y="140" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="349" value="" style="edgeStyle=segmentEdgeStyle;endArrow=classic;html=1;curved=0;rounded=1;endSize=8;startSize=8;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#FFFFFF;fontColor=#FFFFFF;dashed=1;" parent="1" source="345" target="347" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="360" y="260" as="sourcePoint"/>
|
||||
<mxPoint x="410" y="210" as="targetPoint"/>
|
||||
<Array as="points">
|
||||
<mxPoint x="175" y="155"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="350" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="351" value="7" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="207.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="352" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="350" target="355" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="630" y="50" as="sourcePoint"/>
|
||||
<mxPoint x="630" y="360" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="353" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="245" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="354" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="252.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="355" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#4F1623;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="130" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="356" value="4" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="207.5" y="140" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="357" value="" style="edgeStyle=segmentEdgeStyle;endArrow=classic;html=1;curved=0;rounded=1;endSize=8;startSize=8;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#FFFFFF;fontColor=#FFFFFF;dashed=1;" parent="1" source="353" target="355" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="450" y="260" as="sourcePoint"/>
|
||||
<mxPoint x="500" y="210" as="targetPoint"/>
|
||||
<Array as="points">
|
||||
<mxPoint x="265" y="155"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="358" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="290" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="359" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="297.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="360" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="358" target="363" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="720" y="50" as="sourcePoint"/>
|
||||
<mxPoint x="720" y="360" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="361" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="335" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="362" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="342.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="363" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#4F1623;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="290" y="130" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="364" value="6" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="297.5" y="140" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="365" value="" style="edgeStyle=segmentEdgeStyle;endArrow=classic;html=1;curved=0;rounded=1;endSize=8;startSize=8;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#FFFFFF;fontColor=#FFFFFF;dashed=1;" parent="1" source="361" target="363" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="540" y="260" as="sourcePoint"/>
|
||||
<mxPoint x="590" y="210" as="targetPoint"/>
|
||||
<Array as="points">
|
||||
<mxPoint x="355" y="155"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="366" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="190" width="380" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="367" value="<font face="Klavika" style="font-size: 17px;">Shared</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="145" y="190" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="368" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="220" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="369" value="13" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="27.5" y="230" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="370" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="368" target="373" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="450" y="210" as="sourcePoint"/>
|
||||
<mxPoint x="450" y="520" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="371" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="65" y="220" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="372" value="13" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="72.5" y="230" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="373" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#4F1623;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="290" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="374" value="0" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="27.5" y="300" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="375" value="" style="edgeStyle=segmentEdgeStyle;endArrow=classic;html=1;curved=0;rounded=1;endSize=8;startSize=8;entryX=1;entryY=0.5;entryDx=0;entryDy=0;strokeColor=#FFFFFF;fontColor=#FFFFFF;dashed=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="376" target="373" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="270" y="420" as="sourcePoint"/>
|
||||
<mxPoint x="320" y="370" as="targetPoint"/>
|
||||
<Array as="points">
|
||||
<mxPoint x="130" y="315"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="376" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="110" y="220" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="377" value="8" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="117.5" y="230" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="379" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="155" y="220" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="380" value="2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="162.5" y="230" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="384" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="220" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="385" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="207.5" y="230" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="386" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="384" target="389" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="630" y="210" as="sourcePoint"/>
|
||||
<mxPoint x="630" y="520" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="387" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="245" y="220" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="388" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="252.5" y="230" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="389" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#4F1623;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="290" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="390" value="4" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="207.5" y="300" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="391" value="" style="edgeStyle=segmentEdgeStyle;endArrow=classic;html=1;curved=0;rounded=1;endSize=8;startSize=8;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#FFFFFF;fontColor=#FFFFFF;dashed=1;" parent="1" source="392" target="389" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="450" y="420" as="sourcePoint"/>
|
||||
<mxPoint x="500" y="370" as="targetPoint"/>
|
||||
<Array as="points">
|
||||
<mxPoint x="310" y="315"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="392" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="290" y="220" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="393" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="297.5" y="230" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="395" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="335" y="220" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="396" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="342.5" y="230" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="400" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="339" target="368" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="50" y="120" as="sourcePoint"/>
|
||||
<mxPoint x="50" y="140" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="401" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="347" target="376" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="50" y="190" as="sourcePoint"/>
|
||||
<mxPoint x="50" y="230" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="402" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="355" target="384" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="60" y="200" as="sourcePoint"/>
|
||||
<mxPoint x="60" y="240" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="403" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="363" target="392" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="70" y="210" as="sourcePoint"/>
|
||||
<mxPoint x="70" y="250" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="404" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="350" width="380" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="405" value="<font face="Klavika" style="font-size: 17px;">Shared</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="145" y="350" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="406" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="380" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="407" value="13" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="27.5" y="390" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="408" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="406" target="411" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="450" y="370" as="sourcePoint"/>
|
||||
<mxPoint x="450" y="680" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="409" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="65" y="380" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="410" value="13" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="72.5" y="390" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="411" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#4F1623;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="450" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="412" value="0" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="27.5" y="460" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="413" value="" style="edgeStyle=segmentEdgeStyle;endArrow=classic;html=1;curved=0;rounded=1;endSize=8;startSize=8;entryX=1;entryY=0.5;entryDx=0;entryDy=0;strokeColor=#FFFFFF;fontColor=#FFFFFF;dashed=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="418" target="411" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="270" y="580" as="sourcePoint"/>
|
||||
<mxPoint x="320" y="530" as="targetPoint"/>
|
||||
<Array as="points">
|
||||
<mxPoint x="220" y="475"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="414" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="110" y="380" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="415" value="8" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="117.5" y="390" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="416" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="155" y="380" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="417" value="2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="162.5" y="390" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="418" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="380" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="419" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="207.5" y="390" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="421" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="245" y="380" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="422" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="252.5" y="390" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="426" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="290" y="380" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="427" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="297.5" y="390" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="428" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="335" y="380" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="429" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="342.5" y="390" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="430" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="373" target="406" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="50" y="190" as="sourcePoint"/>
|
||||
<mxPoint x="50" y="230" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="431" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="389" target="418" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="60" y="200" as="sourcePoint"/>
|
||||
<mxPoint x="60" y="240" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="432" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="510" width="380" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="433" value="<font face="Klavika" style="font-size: 17px;">Shared</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="145" y="510" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="434" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="540" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="435" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="27.5" y="550" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="436" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="411" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="450" y="530" as="sourcePoint"/>
|
||||
<mxPoint x="40" y="540" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="437" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="65" y="540" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="438" value="13" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="72.5" y="550" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="439" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="110" y="540" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="440" value="8" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="117.5" y="550" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="441" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="155" y="540" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="442" value="2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="162.5" y="550" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="443" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="540" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="444" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="207.5" y="550" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="445" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="245" y="540" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="446" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="252.5" y="550" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="447" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="290" y="540" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="448" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="297.5" y="550" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="449" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="335" y="540" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="450" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="342.5" y="550" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="451" value="Thread IDs" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;whiteSpace=wrap;rotation=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="400" y="140" width="62.5" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="454" value="Data snapshot" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;whiteSpace=wrap;rotation=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="400" y="50" width="62.5" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="460" value="Thread IDs" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;whiteSpace=wrap;rotation=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="400" y="300" width="62.5" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="461" value="Data snapshot" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;whiteSpace=wrap;rotation=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="400" y="210" width="62.5" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="462" value="Thread IDs" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;whiteSpace=wrap;rotation=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="400" y="460" width="62.5" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="463" value="Data snapshot" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;whiteSpace=wrap;rotation=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="400" y="370" width="62.5" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="464" value="Data snapshot" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;whiteSpace=wrap;rotation=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="400" y="530" width="62.5" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
После Ширина: | Высота: | Размер: 61 KiB |
@@ -0,0 +1,142 @@
|
||||
<mxfile host="65bd71144e">
|
||||
<diagram id="zBbb_w2fufU70cdOGtND" name="1 oldal">
|
||||
<mxGraphModel dx="992" dy="899" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="660" pageHeight="610" background="none" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#5E5B61;fontColor=#FFFFFF;strokeColor=none;spacing=0;" parent="1" vertex="1">
|
||||
<mxGeometry width="490" height="550" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="3" value="Parallel Reduce" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="205" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="70" y="30" width="330" height="120" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6" value="<font face="Klavika" style="font-size: 17px;">Input</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="205" y="30" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="107" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="300" y="60" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="141" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="190" y="60" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="143" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#523E43;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="160" width="220" height="120" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="142" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="80" y="60" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="145" value="8" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="315" y="85" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="146" value="13" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="205" y="85" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="147" value="5" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="95" y="85" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="284" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="190" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="285" value="z" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="35" y="215" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="288" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="130" y="190" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="289" value="5" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="145" y="215" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="290" value="<font face="Klavika" style="font-size: 17px;">f(z,5)</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="90" y="160" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="291" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="142" target="288" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="124.5" y="140" as="sourcePoint"/>
|
||||
<mxPoint x="125" y="180" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="292" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#523E43;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="240" y="160" width="220" height="120" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="293" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="250" y="190" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="294" value="13" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="265" y="215" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="295" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="360" y="190" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="296" value="8" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="375" y="215" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="297" value="<font face="Klavika" style="font-size: 17px;">f(13,8)</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="320" y="160" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="299" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#523E43;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="125" y="290" width="220" height="120" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="300" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="135" y="320" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="301" value="5" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="150" y="345" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="302" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="245" y="320" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="303" value="13" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="260" y="345" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="304" value="<font face="Klavika" style="font-size: 17px;">f(f(z,5),f(13,8))<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="205" y="290" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="310" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="175" y="420" width="120" height="120" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="311" value="<font face="Klavika" style="font-size: 17px;">Result</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="205" y="420" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="312" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="190" y="450" width="90" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="313" value="13" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="205" y="475" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="314" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="107" target="295" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="135" y="150" as="sourcePoint"/>
|
||||
<mxPoint x="185" y="200" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="315" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="141" target="293" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="355" y="150" as="sourcePoint"/>
|
||||
<mxPoint x="415" y="200" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="316" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="143" target="300" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="135" y="150" as="sourcePoint"/>
|
||||
<mxPoint x="185" y="200" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="317" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="292" target="302" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="145" y="160" as="sourcePoint"/>
|
||||
<mxPoint x="195" y="210" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="318" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0;entryY=0;entryDx=0;entryDy=0;exitX=0.25;exitY=1;exitDx=0;exitDy=0;" parent="1" source="299" target="312" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="130" y="290" as="sourcePoint"/>
|
||||
<mxPoint x="190" y="330" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
После Ширина: | Высота: | Размер: 20 KiB |
@@ -0,0 +1,442 @@
|
||||
<mxfile host="65bd71144e">
|
||||
<diagram id="zBbb_w2fufU70cdOGtND" name="1 oldal">
|
||||
<mxGraphModel dx="1054" dy="1139" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="660" pageHeight="610" background="none" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="450" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#5E5B61;fontColor=#FFFFFF;strokeColor=none;spacing=0;" vertex="1" parent="1">
|
||||
<mxGeometry width="480" height="610" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="451" value="Reduced Divergence Reduction" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="210" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="452" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="10" y="30" width="380" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="453" value="<font face="Klavika" style="font-size: 17px;">Shared</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="145" y="30" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="454" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="20" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="455" value="5" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="27.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="456" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="454" target="459">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="450" y="50" as="sourcePoint"/>
|
||||
<mxPoint x="450" y="360" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="457" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="65" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="458" value="13" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="72.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="459" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#4F1623;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="20" y="130" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="460" value="0" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="27.5" y="140" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="461" value="" style="edgeStyle=segmentEdgeStyle;endArrow=classic;html=1;curved=0;rounded=1;endSize=8;startSize=8;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#FFFFFF;fontColor=#FFFFFF;dashed=1;" edge="1" parent="1" source="457" target="459">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="270" y="260" as="sourcePoint"/>
|
||||
<mxPoint x="320" y="210" as="targetPoint"/>
|
||||
<Array as="points">
|
||||
<mxPoint x="85" y="155"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="462" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="110" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="463" value="8" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="117.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="464" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="462" target="467">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="540" y="50" as="sourcePoint"/>
|
||||
<mxPoint x="540" y="360" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="465" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="155" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="466" value="2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="162.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="467" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#4F1623;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="110" y="130" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="468" value="1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="117.5" y="140" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="469" value="" style="edgeStyle=segmentEdgeStyle;endArrow=classic;html=1;curved=0;rounded=1;endSize=8;startSize=8;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#FFFFFF;fontColor=#FFFFFF;dashed=1;" edge="1" parent="1" source="465" target="467">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="360" y="260" as="sourcePoint"/>
|
||||
<mxPoint x="410" y="210" as="targetPoint"/>
|
||||
<Array as="points">
|
||||
<mxPoint x="175" y="155"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="470" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="200" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="471" value="7" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="207.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="472" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="470" target="475">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="630" y="50" as="sourcePoint"/>
|
||||
<mxPoint x="630" y="360" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="473" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="245" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="474" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="252.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="475" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#4F1623;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="200" y="130" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="476" value="2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="207.5" y="140" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="477" value="" style="edgeStyle=segmentEdgeStyle;endArrow=classic;html=1;curved=0;rounded=1;endSize=8;startSize=8;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#FFFFFF;fontColor=#FFFFFF;dashed=1;" edge="1" parent="1" source="473" target="475">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="450" y="260" as="sourcePoint"/>
|
||||
<mxPoint x="500" y="210" as="targetPoint"/>
|
||||
<Array as="points">
|
||||
<mxPoint x="265" y="155"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="478" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="290" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="479" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="297.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="480" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="478" target="483">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="720" y="50" as="sourcePoint"/>
|
||||
<mxPoint x="720" y="360" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="481" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="335" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="482" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="342.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="483" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#4F1623;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="290" y="130" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="484" value="3" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="297.5" y="140" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="485" value="" style="edgeStyle=segmentEdgeStyle;endArrow=classic;html=1;curved=0;rounded=1;endSize=8;startSize=8;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#FFFFFF;fontColor=#FFFFFF;dashed=1;" edge="1" parent="1" source="481" target="483">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="540" y="260" as="sourcePoint"/>
|
||||
<mxPoint x="590" y="210" as="targetPoint"/>
|
||||
<Array as="points">
|
||||
<mxPoint x="355" y="155"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="486" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="10" y="190" width="380" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="487" value="<font face="Klavika" style="font-size: 17px;">Shared</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="145" y="190" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="488" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="20" y="220" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="489" value="13" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="27.5" y="230" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="490" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="488" target="493">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="450" y="210" as="sourcePoint"/>
|
||||
<mxPoint x="450" y="520" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="491" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="65" y="220" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="492" value="13" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="72.5" y="230" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="493" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#4F1623;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="20" y="290" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="494" value="0" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="27.5" y="300" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="495" value="" style="edgeStyle=segmentEdgeStyle;endArrow=classic;html=1;curved=0;rounded=1;endSize=8;startSize=8;entryX=1;entryY=0.5;entryDx=0;entryDy=0;strokeColor=#FFFFFF;fontColor=#FFFFFF;dashed=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="496" target="493">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="270" y="420" as="sourcePoint"/>
|
||||
<mxPoint x="320" y="370" as="targetPoint"/>
|
||||
<Array as="points">
|
||||
<mxPoint x="130" y="315"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="496" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="110" y="220" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="497" value="8" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="117.5" y="230" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="498" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="155" y="220" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="499" value="2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="162.5" y="230" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="500" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="200" y="220" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="501" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="207.5" y="230" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="502" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="500" target="505">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="630" y="210" as="sourcePoint"/>
|
||||
<mxPoint x="630" y="520" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="503" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="245" y="220" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="504" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="252.5" y="230" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="505" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#4F1623;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="200" y="290" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="506" value="1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="207.5" y="300" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="507" value="" style="edgeStyle=segmentEdgeStyle;endArrow=classic;html=1;curved=0;rounded=1;endSize=8;startSize=8;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#FFFFFF;fontColor=#FFFFFF;dashed=1;" edge="1" parent="1" source="508" target="505">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="450" y="420" as="sourcePoint"/>
|
||||
<mxPoint x="500" y="370" as="targetPoint"/>
|
||||
<Array as="points">
|
||||
<mxPoint x="310" y="315"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="508" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="290" y="220" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="509" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="297.5" y="230" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="510" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="335" y="220" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="511" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="342.5" y="230" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="512" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="459" target="488">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="50" y="120" as="sourcePoint"/>
|
||||
<mxPoint x="50" y="140" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="513" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="467" target="496">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="50" y="190" as="sourcePoint"/>
|
||||
<mxPoint x="50" y="230" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="514" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="475" target="500">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="60" y="200" as="sourcePoint"/>
|
||||
<mxPoint x="60" y="240" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="515" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="483" target="508">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="70" y="210" as="sourcePoint"/>
|
||||
<mxPoint x="70" y="250" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="516" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="10" y="350" width="380" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="517" value="<font face="Klavika" style="font-size: 17px;">Shared</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="145" y="350" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="518" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="20" y="380" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="519" value="13" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="27.5" y="390" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="520" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="518" target="523">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="450" y="370" as="sourcePoint"/>
|
||||
<mxPoint x="450" y="680" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="521" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="65" y="380" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="522" value="13" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="72.5" y="390" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="523" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#4F1623;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="20" y="450" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="524" value="0" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="27.5" y="460" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="525" value="" style="edgeStyle=segmentEdgeStyle;endArrow=classic;html=1;curved=0;rounded=1;endSize=8;startSize=8;entryX=1;entryY=0.5;entryDx=0;entryDy=0;strokeColor=#FFFFFF;fontColor=#FFFFFF;dashed=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="530" target="523">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="270" y="580" as="sourcePoint"/>
|
||||
<mxPoint x="320" y="530" as="targetPoint"/>
|
||||
<Array as="points">
|
||||
<mxPoint x="220" y="475"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="526" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="110" y="380" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="527" value="8" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="117.5" y="390" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="528" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="155" y="380" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="529" value="2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="162.5" y="390" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="530" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="200" y="380" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="531" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="207.5" y="390" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="532" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="245" y="380" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="533" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="252.5" y="390" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="534" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="290" y="380" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="535" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="297.5" y="390" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="536" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="335" y="380" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="537" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="342.5" y="390" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="538" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="493" target="518">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="50" y="190" as="sourcePoint"/>
|
||||
<mxPoint x="50" y="230" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="539" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="505" target="530">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="60" y="200" as="sourcePoint"/>
|
||||
<mxPoint x="60" y="240" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="540" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="10" y="510" width="380" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="541" value="<font face="Klavika" style="font-size: 17px;">Shared</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="145" y="510" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="542" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="20" y="540" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="543" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="27.5" y="550" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="544" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="523">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="450" y="530" as="sourcePoint"/>
|
||||
<mxPoint x="40" y="540" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="545" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="65" y="540" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="546" value="13" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="72.5" y="550" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="547" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="110" y="540" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="548" value="8" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="117.5" y="550" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="549" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="155" y="540" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="550" value="2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="162.5" y="550" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="551" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="200" y="540" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="552" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="207.5" y="550" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="553" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="245" y="540" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="554" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="252.5" y="550" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="555" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="290" y="540" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="556" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="297.5" y="550" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="557" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="335" y="540" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="558" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="342.5" y="550" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="559" value="Thread IDs" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;whiteSpace=wrap;rotation=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="400" y="140" width="62.5" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="560" value="Data snapshot" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;whiteSpace=wrap;rotation=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="400" y="50" width="62.5" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="561" value="Thread IDs" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;whiteSpace=wrap;rotation=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="400" y="300" width="62.5" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="562" value="Data snapshot" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;whiteSpace=wrap;rotation=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="400" y="210" width="62.5" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="563" value="Thread IDs" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;whiteSpace=wrap;rotation=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="400" y="460" width="62.5" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="564" value="Data snapshot" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;whiteSpace=wrap;rotation=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="400" y="370" width="62.5" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="565" value="Data snapshot" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;whiteSpace=wrap;rotation=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="400" y="530" width="62.5" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
После Ширина: | Высота: | Размер: 61 KiB |
@@ -0,0 +1,421 @@
|
||||
<mxfile host="65bd71144e">
|
||||
<diagram id="zBbb_w2fufU70cdOGtND" name="1 oldal">
|
||||
<mxGraphModel dx="670" dy="996" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="660" pageHeight="610" background="none" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#5E5B61;fontColor=#FFFFFF;strokeColor=none;spacing=0;" parent="1" vertex="1">
|
||||
<mxGeometry width="480" height="690" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="3" value="Warp reduction" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="210" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#523E43;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="30" width="380" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6" value="<font face="Klavika" style="font-size: 17px;">Local</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="170" y="30" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="142" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="147" value="5" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="27.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="305" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="142" target="339" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="450" y="50" as="sourcePoint"/>
|
||||
<mxPoint x="450" y="360" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="315" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="65" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="316" value="13" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="72.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="339" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#4F1623;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="180" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="340" value="0" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="27.5" y="190" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="342" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="110" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="343" value="8" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="117.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="344" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="315" target="347" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="540" y="50" as="sourcePoint"/>
|
||||
<mxPoint x="540" y="360" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="345" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="155" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="346" value="2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="162.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="347" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#4F1623;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="65" y="180" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="348" value="1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="72.5" y="190" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="350" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="351" value="7" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="207.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="352" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="342" target="355" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="630" y="50" as="sourcePoint"/>
|
||||
<mxPoint x="630" y="360" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="353" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="245" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="354" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="252.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="355" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#4F1623;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="110" y="180" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="356" value="2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="117.5" y="190" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="358" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="290" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="359" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="297.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="360" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" target="363" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="175" y="110" as="sourcePoint"/>
|
||||
<mxPoint x="720" y="360" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="361" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="335" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="362" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="342.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="363" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#4F1623;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="155" y="180" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="364" value="3" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="162.5" y="190" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="366" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#523E43;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="240" width="380" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="367" value="<span style="font-family: Klavika;">Local</span>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="170" y="240" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="368" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="270" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="369" value="7" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="27.5" y="280" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="371" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="65" y="270" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="372" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="72.5" y="280" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="376" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="110" y="270" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="377" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="117.5" y="280" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="379" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="155" y="270" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="380" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="162.5" y="280" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="384" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="270" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="385" value="7" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="207.5" y="280" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="387" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="245" y="270" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="388" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="252.5" y="280" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="392" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="290" y="270" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="393" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="297.5" y="280" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="395" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="335" y="270" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="396" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="342.5" y="280" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="400" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="339" target="368" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="50" y="110" as="sourcePoint"/>
|
||||
<mxPoint x="50" y="130" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="401" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="347" target="371" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="50" y="180" as="sourcePoint"/>
|
||||
<mxPoint x="50" y="220" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="402" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="355" target="376" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="60" y="190" as="sourcePoint"/>
|
||||
<mxPoint x="60" y="230" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="403" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="363" target="379" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="70" y="200" as="sourcePoint"/>
|
||||
<mxPoint x="70" y="240" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="451" value="" style="endArrow=classicThin;html=1;rounded=1;endSize=8;startSize=8;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#FFFFFF;fontColor=#FFFFFF;exitX=0.5;exitY=1;exitDx=0;exitDy=0;endFill=1;" parent="1" source="350" target="339" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="140" y="310" as="sourcePoint"/>
|
||||
<mxPoint x="70" y="355" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="452" value="" style="endArrow=classicThin;html=1;rounded=1;endSize=8;startSize=8;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#FFFFFF;fontColor=#FFFFFF;exitX=0.5;exitY=1;exitDx=0;exitDy=0;endFill=1;" parent="1" source="353" target="347" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="230" y="120" as="sourcePoint"/>
|
||||
<mxPoint x="50" y="170" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="453" value="" style="endArrow=classic;html=1;rounded=1;fontColor=#FFFFFF;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#FFFFFF;" parent="1" source="358" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="275" y="120" as="sourcePoint"/>
|
||||
<mxPoint x="130" y="180" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="454" value="" style="endArrow=classicThin;html=1;rounded=1;endSize=8;startSize=8;fontColor=#FFFFFF;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#FFFFFF;endFill=1;" parent="1" source="361" target="363" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="320" y="120" as="sourcePoint"/>
|
||||
<mxPoint x="140" y="200" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="481" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#4F1623;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="370" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="482" value="0" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="27.5" y="380" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="483" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#4F1623;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="65" y="370" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="484" value="1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="72.5" y="380" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="489" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#523E43;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="430" width="380" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="490" value="<span style="font-family: Klavika;">Local</span>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="170" y="430" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="491" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="460" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="492" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="27.5" y="470" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="493" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="65" y="460" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="494" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="72.5" y="470" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="495" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="110" y="460" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="496" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="117.5" y="470" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="497" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="155" y="460" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="498" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="162.5" y="470" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="499" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="460" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="500" value="7" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="207.5" y="470" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="501" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="245" y="460" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="502" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="252.5" y="470" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="503" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="290" y="460" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="504" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="297.5" y="470" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="505" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="335" y="460" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="506" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="342.5" y="470" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="507" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="481" target="491" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="50" y="300" as="sourcePoint"/>
|
||||
<mxPoint x="50" y="320" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="508" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="483" target="493" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="50" y="370" as="sourcePoint"/>
|
||||
<mxPoint x="50" y="410" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="511" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="368" target="481" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="50" y="240" as="sourcePoint"/>
|
||||
<mxPoint x="50" y="280" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="512" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="371" target="483" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="60" y="250" as="sourcePoint"/>
|
||||
<mxPoint x="60" y="290" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="513" value="" style="endArrow=classicThin;html=1;rounded=1;endSize=8;startSize=8;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#FFFFFF;fontColor=#FFFFFF;exitX=0.5;exitY=1;exitDx=0;exitDy=0;endFill=1;" parent="1" source="376" target="481" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="230" y="120" as="sourcePoint"/>
|
||||
<mxPoint x="50" y="190" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="514" value="" style="endArrow=classicThin;html=1;rounded=1;endSize=8;startSize=8;strokeColor=#FFFFFF;fontColor=#FFFFFF;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;endFill=1;" parent="1" source="379" target="483" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="140" y="330" as="sourcePoint"/>
|
||||
<mxPoint x="80" y="370" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="516" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#4F1623;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="530" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="517" value="0" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="27.5" y="540" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="520" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#523E43;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="590" width="380" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="521" value="<span style="font-family: Klavika;">Local<br></span>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="170" y="590" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="522" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="620" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="523" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="27.5" y="630" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="524" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="65" y="620" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="525" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="72.5" y="630" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="526" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="110" y="620" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="527" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="117.5" y="630" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="528" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="155" y="620" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="529" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="162.5" y="630" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="530" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="620" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="531" value="7" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="207.5" y="630" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="532" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="245" y="620" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="533" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="252.5" y="630" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="534" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="290" y="620" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="535" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="297.5" y="630" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="536" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="335" y="620" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="537" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="342.5" y="630" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="538" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="516" target="522" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="50" y="460" as="sourcePoint"/>
|
||||
<mxPoint x="50" y="480" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="540" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="491" target="516" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="50" y="430" as="sourcePoint"/>
|
||||
<mxPoint x="50" y="470" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="541" value="" style="endArrow=classicThin;html=1;rounded=1;endSize=8;startSize=8;strokeColor=#FFFFFF;fontColor=#FFFFFF;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;endFill=1;" parent="1" source="493" target="516" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="185" y="330" as="sourcePoint"/>
|
||||
<mxPoint x="95" y="380" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="542" value="Thread IDs" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;whiteSpace=wrap;rotation=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="400" y="170" width="62.5" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="543" value="Data snapshot" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;whiteSpace=wrap;rotation=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="400" y="50" width="62.5" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="544" value="Thread IDs" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;whiteSpace=wrap;rotation=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="400" y="370" width="62.5" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="545" value="Data snapshot" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;whiteSpace=wrap;rotation=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="400" y="260" width="62.5" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="546" value="Thread IDs" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;whiteSpace=wrap;rotation=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="400" y="540" width="62.5" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="547" value="Data snapshot" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;whiteSpace=wrap;rotation=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="400" y="450" width="62.5" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="548" value="Data snapshot" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;whiteSpace=wrap;rotation=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="400" y="610" width="62.5" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
После Ширина: | Высота: | Размер: 60 KiB |
@@ -0,0 +1,707 @@
|
||||
<mxfile host="65bd71144e">
|
||||
<diagram id="zBbb_w2fufU70cdOGtND" name="1 oldal">
|
||||
<mxGraphModel dx="983" dy="1266" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="660" pageHeight="610" background="none" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="903" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#363538;fontColor=#FFFFFF;strokeColor=none;spacing=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="-30" y="-70" width="900" height="920" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="896" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#5E5B61;fontColor=#FFFFFF;strokeColor=none;spacing=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="-10" y="590" width="150" height="240" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#5E5B61;fontColor=#FFFFFF;strokeColor=none;spacing=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="-10" y="-10" width="420" height="450" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="3" value="Warp reduction" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="170" y="-10" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#523E43;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="30" width="380" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6" value="<font face="Klavika" style="font-size: 17px;">Local</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="170" y="30" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="142" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="147" value="5" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="27.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="315" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="65" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="316" value="13" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="72.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="342" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="110" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="343" value="8" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="117.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="345" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="155" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="346" value="2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="162.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="350" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="351" value="7" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="207.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="353" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="245" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="354" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="252.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="358" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="290" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="359" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="297.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="361" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="335" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="362" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="342.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="366" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#523E43;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="130" width="380" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="368" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="160" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="369" value="7" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="27.5" y="170" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="371" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="65" y="160" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="372" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="72.5" y="170" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="376" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="110" y="160" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="377" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="117.5" y="170" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="379" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="155" y="160" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="380" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="162.5" y="170" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="384" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="160" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="385" value="7" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="207.5" y="170" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="387" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="245" y="160" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="388" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="252.5" y="170" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="392" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="290" y="160" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="393" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="297.5" y="170" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="395" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="335" y="160" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="396" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="342.5" y="170" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="451" value="" style="endArrow=classicThin;html=1;rounded=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;endFill=1;" parent="1" source="350" target="368" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="140" y="310" as="sourcePoint"/>
|
||||
<mxPoint x="40" y="180" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="452" value="" style="endArrow=classicThin;html=1;rounded=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#FFFFFF;fontColor=#FFFFFF;exitX=0.5;exitY=1;exitDx=0;exitDy=0;endFill=1;" parent="1" source="353" target="371" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="230" y="120" as="sourcePoint"/>
|
||||
<mxPoint x="85" y="180" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="453" value="" style="endArrow=classicThin;html=1;rounded=1;fontColor=#FFFFFF;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#FFFFFF;endFill=1;" parent="1" source="358" target="376" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="275" y="120" as="sourcePoint"/>
|
||||
<mxPoint x="130" y="180" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="489" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#523E43;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="230" width="380" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="490" value="<span style="font-family: Klavika;">Local</span>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="170" y="230" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="491" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="260" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="492" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="27.5" y="270" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="493" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="65" y="260" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="494" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="72.5" y="270" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="495" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="110" y="260" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="496" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="117.5" y="270" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="497" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="155" y="260" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="498" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="162.5" y="270" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="499" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="260" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="500" value="7" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="207.5" y="270" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="501" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="245" y="260" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="502" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="252.5" y="270" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="503" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="290" y="260" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="504" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="297.5" y="270" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="505" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="335" y="260" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="506" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="342.5" y="270" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="511" value="" style="endArrow=classicThin;html=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;endFill=1;" parent="1" source="368" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="50" y="130" as="sourcePoint"/>
|
||||
<mxPoint x="40" y="260" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="512" value="" style="endArrow=classicThin;html=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;endFill=1;" parent="1" source="371" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="60" y="140" as="sourcePoint"/>
|
||||
<mxPoint x="85" y="260" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="513" value="" style="endArrow=classicThin;html=1;rounded=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#FFFFFF;fontColor=#FFFFFF;exitX=0.5;exitY=1;exitDx=0;exitDy=0;endFill=1;" parent="1" source="376" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="230" y="10" as="sourcePoint"/>
|
||||
<mxPoint x="40" y="260" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="514" value="" style="endArrow=classicThin;html=1;rounded=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;endFill=1;" parent="1" source="379" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="140" y="220" as="sourcePoint"/>
|
||||
<mxPoint x="85" y="260" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="520" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#523E43;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="330" width="380" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="521" value="<span style="font-family: Klavika;">Local<br></span>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="170" y="330" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="522" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="360" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="523" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="27.5" y="370" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="524" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="65" y="360" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="525" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="72.5" y="370" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="526" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="110" y="360" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="527" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="117.5" y="370" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="528" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="155" y="360" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="529" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="162.5" y="370" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="530" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="360" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="531" value="7" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="207.5" y="370" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="532" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="245" y="360" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="533" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="252.5" y="370" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="534" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="290" y="360" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="535" value="23" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="297.5" y="370" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="536" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="335" y="360" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="537" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="342.5" y="370" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="540" value="" style="endArrow=classicThin;html=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;endFill=1;" parent="1" source="491" target="522" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="50" y="230" as="sourcePoint"/>
|
||||
<mxPoint x="40" y="330" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="541" value="" style="endArrow=classicThin;html=1;rounded=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;endFill=1;" parent="1" source="493" target="522" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="185" y="130" as="sourcePoint"/>
|
||||
<mxPoint x="60" y="355" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="305" value="" style="endArrow=classicThin;html=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;exitX=0.5;exitY=1;exitDx=0;exitDy=0;endFill=1;" parent="1" source="142" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="450" y="50" as="sourcePoint"/>
|
||||
<mxPoint x="40" y="160" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="344" value="" style="endArrow=classicThin;html=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;exitX=0.5;exitY=1;exitDx=0;exitDy=0;endFill=1;" parent="1" source="315" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="540" y="50" as="sourcePoint"/>
|
||||
<mxPoint x="85" y="160" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="352" value="" style="endArrow=classicThin;html=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;exitX=0.5;exitY=1;exitDx=0;exitDy=0;endFill=1;" parent="1" source="342" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="630" y="50" as="sourcePoint"/>
|
||||
<mxPoint x="130" y="160" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="360" value="" style="endArrow=classicThin;html=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;endFill=1;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="175" y="110" as="sourcePoint"/>
|
||||
<mxPoint x="175" y="160" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="665" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#5E5B61;fontColor=#FFFFFF;strokeColor=none;spacing=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="430" y="-10" width="420" height="450" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="666" value="Warp reduction" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="620" y="-10" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="667" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#523E43;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="450" y="30" width="380" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="668" value="<font face="Klavika" style="font-size: 17px;">Local</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="610" y="30" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="669" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="460" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="670" value="3" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="467.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="671" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="505" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="672" value="2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="512.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="673" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="550" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="674" value="4" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="557.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="675" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="595" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="676" value="1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="602.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="677" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="640" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="678" value="7" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="647.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="679" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="685" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="680" value="11" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="692.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="681" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="730" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="682" value="8" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="737.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="683" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="775" y="60" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="684" value="14" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="782.5" y="70" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="685" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#523E43;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="450" y="130" width="380" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="687" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="460" y="160" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="688" value="10" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="467.5" y="170" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="689" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="505" y="160" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="690" value="13" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="512.5" y="170" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="691" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="550" y="160" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="692" value="12" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="557.5" y="170" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="693" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="595" y="160" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="694" value="15" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="602.5" y="170" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="695" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="640" y="160" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="696" value="7" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="647.5" y="170" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="697" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="685" y="160" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="698" value="11" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="692.5" y="170" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="699" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="730" y="160" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="700" value="8" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="737.5" y="170" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="701" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="775" y="160" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="702" value="14" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="782.5" y="170" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="703" value="" style="endArrow=classicThin;html=1;rounded=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;endFill=1;" parent="1" source="677" target="687" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="580" y="310" as="sourcePoint"/>
|
||||
<mxPoint x="480" y="180" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="704" value="" style="endArrow=classicThin;html=1;rounded=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#FFFFFF;fontColor=#FFFFFF;exitX=0.5;exitY=1;exitDx=0;exitDy=0;endFill=1;" parent="1" source="679" target="689" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="670" y="120" as="sourcePoint"/>
|
||||
<mxPoint x="525" y="180" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="706" value="" style="endArrow=classicThin;html=1;rounded=1;fontColor=#FFFFFF;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#FFFFFF;endFill=1;" parent="1" source="683" target="693" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="760" y="120" as="sourcePoint"/>
|
||||
<mxPoint x="615" y="180" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="707" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#523E43;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="450" y="230" width="380" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="708" value="<span style="font-family: Klavika;">Local</span>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="610" y="230" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="709" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="460" y="260" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="710" value="22" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="467.5" y="270" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="711" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="505" y="260" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="712" value="28" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="512.5" y="270" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="713" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="550" y="260" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="714" value="12" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="557.5" y="270" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="715" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="595" y="260" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="716" value="15" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="602.5" y="270" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="717" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="640" y="260" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="718" value="7" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="647.5" y="270" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="719" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="685" y="260" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="720" value="11" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="692.5" y="270" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="721" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="730" y="260" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="722" value="8" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="737.5" y="270" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="723" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="775" y="260" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="724" value="14" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="782.5" y="270" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="725" value="" style="endArrow=classicThin;html=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;endFill=1;" parent="1" source="687" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="490" y="130" as="sourcePoint"/>
|
||||
<mxPoint x="480" y="260" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="726" value="" style="endArrow=classicThin;html=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;endFill=1;" parent="1" source="689" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="500" y="140" as="sourcePoint"/>
|
||||
<mxPoint x="525" y="260" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="727" value="" style="endArrow=classicThin;html=1;rounded=1;endSize=8;startSize=8;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#FFFFFF;fontColor=#FFFFFF;exitX=0.5;exitY=1;exitDx=0;exitDy=0;endFill=1;" parent="1" source="691" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="670" y="10" as="sourcePoint"/>
|
||||
<mxPoint x="480" y="260" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="728" value="" style="endArrow=classicThin;html=1;rounded=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;endFill=1;" parent="1" source="693" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="580" y="220" as="sourcePoint"/>
|
||||
<mxPoint x="525" y="260" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="729" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#523E43;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="450" y="330" width="380" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="730" value="<span style="font-family: Klavika;">Local<br></span>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="610" y="330" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="731" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="460" y="360" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="732" value="50" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="467.5" y="370" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="733" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="505" y="360" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="734" value="28" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="512.5" y="370" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="735" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="550" y="360" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="736" value="12" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="557.5" y="370" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="737" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="595" y="360" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="738" value="15" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="602.5" y="370" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="739" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="640" y="360" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="740" value="7" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="647.5" y="370" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="741" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="685" y="360" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="742" value="11" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="692.5" y="370" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="743" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="730" y="360" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="744" value="8" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="737.5" y="370" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="745" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="775" y="360" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="746" value="14" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="782.5" y="370" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="747" value="" style="endArrow=classicThin;html=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;endFill=1;" parent="1" source="709" target="731" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="490" y="230" as="sourcePoint"/>
|
||||
<mxPoint x="480" y="330" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="748" value="" style="endArrow=classicThin;html=1;rounded=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;endFill=1;" parent="1" source="711" target="731" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="625" y="130" as="sourcePoint"/>
|
||||
<mxPoint x="500" y="355" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="749" value="" style="endArrow=classicThin;html=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;exitX=0.5;exitY=1;exitDx=0;exitDy=0;endFill=1;" parent="1" source="669" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="890" y="50" as="sourcePoint"/>
|
||||
<mxPoint x="480" y="160" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="750" value="" style="endArrow=classicThin;html=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;exitX=0.5;exitY=1;exitDx=0;exitDy=0;endFill=1;" parent="1" source="671" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="980" y="50" as="sourcePoint"/>
|
||||
<mxPoint x="525" y="160" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="751" value="" style="endArrow=classicThin;html=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;exitX=0.5;exitY=1;exitDx=0;exitDy=0;endFill=1;" parent="1" source="673" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1070" y="50" as="sourcePoint"/>
|
||||
<mxPoint x="570" y="160" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="752" value="" style="endArrow=classicThin;html=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;endFill=1;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="615" y="110" as="sourcePoint"/>
|
||||
<mxPoint x="615" y="160" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="872" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#523E43;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="10" y="720" width="105" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="873" value="<span style="font-family: Klavika;">Local</span>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="32.5" y="720" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="874" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="20" y="750" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="875" value="92" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="27.5" y="760" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="876" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="65" y="750" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="877" value="50" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="72.5" y="760" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="884" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#523E43;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="10" y="610" width="105" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="885" value="<span style="font-family: Klavika;">Local</span>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="32.5" y="610" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="886" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="20" y="640" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="887" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="27.5" y="650" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="888" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="65" y="640" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="889" value="50" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="72.5" y="650" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="890" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="10" y="470" width="105" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="891" value="<span style="font-family: Klavika;">Shared</span>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="32.5" y="470" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="900" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;dashed=1;strokeColor=#FFFFFF;endArrow=classicThin;endFill=1;" edge="1" parent="1" source="892">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="40" y="640" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="892" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="20" y="500" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="893" value="42" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="27.5" y="510" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="901" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;dashed=1;strokeColor=#FFFFFF;endArrow=classicThin;endFill=1;" edge="1" parent="1" source="894">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="85" y="640" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="894" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="65" y="500" width="40" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="895" value="50" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="72.5" y="510" width="25" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="897" style="html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.104;entryY=1.088;entryDx=0;entryDy=0;entryPerimeter=0;dashed=1;strokeColor=#FFFFFF;endArrow=classicThin;endFill=1;" edge="1" parent="1" source="522" target="891">
|
||||
<mxGeometry relative="1" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="898" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;dashed=1;strokeColor=#FFFFFF;endArrow=classicThin;endFill=1;" edge="1" parent="1" source="731" target="894">
|
||||
<mxGeometry relative="1" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="904" value="Warp reduction with shared memory" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="290" y="-60" width="270" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="367" value="<span style="font-family: Klavika;">Local</span>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="170" y="130" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="686" value="<span style="font-family: Klavika;">Local</span>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="610" y="130" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="907" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.084;entryY=1.029;entryDx=0;entryDy=0;entryPerimeter=0;strokeColor=#FFFFFF;endArrow=classicThin;endFill=1;" edge="1" parent="1" source="361" target="367">
|
||||
<mxGeometry relative="1" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="908" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#FFFFFF;endArrow=classicThin;endFill=1;" edge="1" parent="1" source="681" target="691">
|
||||
<mxGeometry relative="1" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="878" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#FFFFFF;endArrow=classicThin;endFill=1;" edge="1" parent="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="39.999999999999886" y="689.9999999999998" as="sourcePoint"/>
|
||||
<mxPoint x="40" y="750" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="879" style="html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#FFFFFF;endArrow=classicThin;endFill=1;" edge="1" parent="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="85" y="689.9999999999998" as="sourcePoint"/>
|
||||
<mxPoint x="40" y="750" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
После Ширина: | Высота: | Размер: 99 KiB |
|
После Ширина: | Высота: | Размер: 90 KiB |
|
После Ширина: | Высота: | Размер: 14 KiB |
@@ -0,0 +1,187 @@
|
||||
<mxfile host="app.diagrams.net" modified="2024-04-15T15:34:54.047Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:124.0) Gecko/20100101 Firefox/124.0" version="24.2.5" etag="cCeZsuO6-96dwYw9JMeI" type="device">
|
||||
<diagram id="zBbb_w2fufU70cdOGtND" name="1 oldal">
|
||||
<mxGraphModel dx="1728" dy="1360" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="660" pageHeight="610" background="none" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="5927" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#5E5B61;fontColor=#FFFFFF;strokeColor=none;spacing=0;" parent="1" vertex="1">
|
||||
<mxGeometry y="-20" width="740" height="400" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="5928" value="Compute Unit" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Helvetica;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry y="-10" width="740" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="5945" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#9C2A44;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="30" width="590" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="5946" value="<font face="Helvetica">Vector Caches</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="30" width="590" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5953" value="" style="group" vertex="1" connectable="0" parent="1">
|
||||
<mxGeometry x="10" y="90" width="140" height="220" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="5925" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#4F1623;fontColor=#FFFFFF;strokeColor=none;" parent="UvHuP5o6jSuoLTm0AUZA-5953" vertex="1">
|
||||
<mxGeometry width="140" height="220" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="5835" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" parent="UvHuP5o6jSuoLTm0AUZA-5953" vertex="1">
|
||||
<mxGeometry x="10" y="30" width="120" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="5926" value="<font face="Helvetica">SIMD</font> 0" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="UvHuP5o6jSuoLTm0AUZA-5953" vertex="1">
|
||||
<mxGeometry width="140" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5949" value="<font face="Helvetica">Vector ALU<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="UvHuP5o6jSuoLTm0AUZA-5953">
|
||||
<mxGeometry x="16.25" y="40" width="107.5" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5952" value="" style="group" vertex="1" connectable="0" parent="UvHuP5o6jSuoLTm0AUZA-5953">
|
||||
<mxGeometry x="10" y="90" width="120" height="120" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5950" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="UvHuP5o6jSuoLTm0AUZA-5952">
|
||||
<mxGeometry width="120" height="120" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5951" value="<div>Vector</div><div>Register</div><div>File<br></div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="UvHuP5o6jSuoLTm0AUZA-5952">
|
||||
<mxGeometry x="10" y="26.666666666666664" width="100" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5962" value="" style="group" vertex="1" connectable="0" parent="1">
|
||||
<mxGeometry x="310" y="90" width="140" height="220" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5963" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#4F1623;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="UvHuP5o6jSuoLTm0AUZA-5962">
|
||||
<mxGeometry width="140" height="220" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5964" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="UvHuP5o6jSuoLTm0AUZA-5962">
|
||||
<mxGeometry x="10" y="30" width="120" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5965" value="<font face="Helvetica">SIMD 2<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="UvHuP5o6jSuoLTm0AUZA-5962">
|
||||
<mxGeometry width="140" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5966" value="<font face="Helvetica">Vector ALU<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="UvHuP5o6jSuoLTm0AUZA-5962">
|
||||
<mxGeometry x="16.25" y="40" width="107.5" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5967" value="" style="group" vertex="1" connectable="0" parent="UvHuP5o6jSuoLTm0AUZA-5962">
|
||||
<mxGeometry x="10" y="90" width="120" height="120" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5968" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="UvHuP5o6jSuoLTm0AUZA-5967">
|
||||
<mxGeometry width="120" height="120" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5969" value="<div>Vector</div><div>Register<br></div><div>File<br></div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="UvHuP5o6jSuoLTm0AUZA-5967">
|
||||
<mxGeometry x="10" y="26.666666666666664" width="100" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5970" value="" style="group" vertex="1" connectable="0" parent="1">
|
||||
<mxGeometry x="460" y="90" width="140" height="220" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5971" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#4F1623;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="UvHuP5o6jSuoLTm0AUZA-5970">
|
||||
<mxGeometry width="140" height="220" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5972" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="UvHuP5o6jSuoLTm0AUZA-5970">
|
||||
<mxGeometry x="10" y="30" width="120" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5973" value="<font face="Helvetica">SIMD 3<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="UvHuP5o6jSuoLTm0AUZA-5970">
|
||||
<mxGeometry width="140" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5974" value="<font face="Helvetica">Vector ALU<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="UvHuP5o6jSuoLTm0AUZA-5970">
|
||||
<mxGeometry x="16.25" y="40" width="107.5" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5975" value="" style="group" vertex="1" connectable="0" parent="UvHuP5o6jSuoLTm0AUZA-5970">
|
||||
<mxGeometry x="10" y="90" width="120" height="120" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5976" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="UvHuP5o6jSuoLTm0AUZA-5975">
|
||||
<mxGeometry width="120" height="120" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5977" value="<div>Vector</div><div>Register<br></div><div>File<br></div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="UvHuP5o6jSuoLTm0AUZA-5975">
|
||||
<mxGeometry x="10" y="26.666666666666664" width="100" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5981" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.12;exitY=1.005;exitDx=0;exitDy=0;exitPerimeter=0;strokeWidth=2;" edge="1" parent="1" source="5945" target="5926">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="450" y="350" as="sourcePoint" />
|
||||
<mxPoint x="470" y="320" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5982" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.12;exitY=1.005;exitDx=0;exitDy=0;exitPerimeter=0;strokeWidth=2;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="230.5" y="60" as="sourcePoint" />
|
||||
<mxPoint x="229.5" y="90" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5983" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.12;exitY=1.005;exitDx=0;exitDy=0;exitPerimeter=0;strokeWidth=2;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="380.5" y="60" as="sourcePoint" />
|
||||
<mxPoint x="379.5" y="90" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5984" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.12;exitY=1.005;exitDx=0;exitDy=0;exitPerimeter=0;strokeWidth=2;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="530.5" y="60" as="sourcePoint" />
|
||||
<mxPoint x="529.5" y="90" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5985" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.12;exitY=1.005;exitDx=0;exitDy=0;exitPerimeter=0;strokeWidth=2;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="80.5" y="310" as="sourcePoint" />
|
||||
<mxPoint x="79.5" y="340" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5986" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.12;exitY=1.005;exitDx=0;exitDy=0;exitPerimeter=0;strokeWidth=2;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="230.5" y="310" as="sourcePoint" />
|
||||
<mxPoint x="229.5" y="340" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5987" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.12;exitY=1.005;exitDx=0;exitDy=0;exitPerimeter=0;strokeWidth=2;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="380.5" y="310" as="sourcePoint" />
|
||||
<mxPoint x="379.5" y="340" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5988" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.12;exitY=1.005;exitDx=0;exitDy=0;exitPerimeter=0;strokeWidth=2;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="530.5" y="310" as="sourcePoint" />
|
||||
<mxPoint x="529.5" y="340" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5955" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#4F1623;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="160" y="90" width="140" height="220" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5956" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="170" y="120" width="120" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5957" value="<font face="Helvetica">SIMD 1<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="160" y="90" width="140" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5958" value="<font face="Helvetica">Vector ALU<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="1">
|
||||
<mxGeometry x="176.25" y="130" width="107.5" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5959" value="" style="group" vertex="1" connectable="0" parent="1">
|
||||
<mxGeometry x="170" y="180" width="120" height="120" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5960" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" vertex="1" parent="UvHuP5o6jSuoLTm0AUZA-5959">
|
||||
<mxGeometry width="120" height="120" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5961" value="<div>Vector</div><div>Register<br></div><div>File<br></div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" vertex="1" parent="UvHuP5o6jSuoLTm0AUZA-5959">
|
||||
<mxGeometry x="10" y="26.666666666666664" width="100" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5994" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#4F1623;fontColor=#FFFFFF;strokeColor=none;direction=south;" vertex="1" parent="1">
|
||||
<mxGeometry x="610" y="30" width="120" height="340" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5995" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;direction=south;" vertex="1" parent="1">
|
||||
<mxGeometry x="620" y="80" width="100" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5997" value="<font face="Helvetica">Scalar ALU<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;rotation=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="620" y="90" width="100" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-5996" value="Scalar Unit" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;rotation=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="620" y="40" width="100" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-6001" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;direction=south;" vertex="1" parent="1">
|
||||
<mxGeometry x="620" y="140" width="100" height="220" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="UvHuP5o6jSuoLTm0AUZA-6002" value="<div>Scalar</div><div>Register</div><div>File</div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;rotation=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="620" y="140" width="100" height="220" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="5943" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#9C2A44;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="340" width="590" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="5944" value="Local Data Share" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="117.27272727272727" y="340" width="375.45454545454544" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
После Ширина: | Высота: | Размер: 50 KiB |
|
После Ширина: | Высота: | Размер: 450 KiB |
|
После Ширина: | Высота: | Размер: 90 KiB |
|
После Ширина: | Высота: | Размер: 14 KiB |
@@ -0,0 +1,181 @@
|
||||
<mxfile host="65bd71144e" scale="1" border="20">
|
||||
<diagram name="CPU vs GPU Architecture" id="cpu-gpu-arch">
|
||||
<mxGraphModel dx="1781" dy="1008" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="600" pageHeight="300" background="#5E5B61" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="title" value="CPU versus GPU Architecture" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=18;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="20" width="200" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="cpu-container" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#585556;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" vertex="1">
|
||||
<mxGeometry x="70" y="90" width="200" height="150" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="cpu-title" value="CPU" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=16;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="145" y="60" width="50" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="cpu-core-1" value="CPU Core" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="85" y="105" width="70" height="55" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="cpu-core-2" value="CPU Core" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="185" y="105" width="70" height="55" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="cpu-core-3" value="CPU Core" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="85" y="170" width="70" height="55" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="cpu-core-4" value="CPU Core" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="185" y="170" width="70" height="55" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-container" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#585556;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" vertex="1">
|
||||
<mxGeometry x="350" y="91" width="200" height="150" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-title" value="GPU" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=16;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="425" y="60" width="50" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-1-1" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="367.5" y="100" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-1-2" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="392.5" y="100" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-1-3" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="417.5" y="100" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-1-4" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="442.5" y="100" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-1-5" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="467.5" y="100" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-1-6" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="492.5" y="100" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-1-7" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="517.5" y="100" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-2-1" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="367.5" y="123" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-2-2" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="392.5" y="123" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-2-3" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="417.5" y="123" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-2-4" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="442.5" y="123" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-2-5" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="467.5" y="123" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-2-6" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="492.5" y="123" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-2-7" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="517.5" y="123" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-3-1" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="367.5" y="146" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-3-2" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="392.5" y="146" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-3-3" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="417.5" y="146" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-3-4" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="442.5" y="146" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-3-5" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="467.5" y="146" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-3-6" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="492.5" y="146" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-3-7" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="517.5" y="146" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-4-1" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="367.5" y="170" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-4-2" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="392.5" y="170" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-4-3" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="417.5" y="170" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-4-4" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="442.5" y="170" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-4-5" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="467.5" y="170" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-4-6" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="492.5" y="170" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-4-7" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="517.5" y="170" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-5-1" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="367.5" y="193" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-5-2" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="392.5" y="193" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-5-3" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="417.5" y="193" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-5-4" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="442.5" y="193" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-5-5" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="467.5" y="193" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-5-6" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="492.5" y="193" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-5-7" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="517.5" y="193" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-6-1" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="367.5" y="216" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-6-2" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="392.5" y="216" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-6-3" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="417.5" y="216" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-6-4" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="442.5" y="216" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-6-5" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="467.5" y="216" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-6-6" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="492.5" y="216" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-core-6-7" value="CU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;fontSize=8;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="517.5" y="216" width="15" height="15" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="cpu-label-1" value="Large Complex Cores" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=12;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="120" y="250" width="150" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="cpu-label-2" value="High Clock Speed (3-5 GHz)" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=12;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="85" y="270" width="170" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-label-1" value="Many Simple Cores" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=12;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="375" y="250" width="150" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-label-2" value="Lower Clock Speed (1-2 GHz)" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=12;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="362.5" y="270" width="175" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="cpu-memory" value="Large Cache per Core" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#9C2A44;strokeColor=#FFFFFF;fontSize=10;fontFamily=Arial;fontColor=#FFFFFF;align=center;" parent="1" vertex="1">
|
||||
<mxGeometry x="70" y="250" width="200" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu-memory" value="Shared Memory across Cores" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#9C2A44;strokeColor=#FFFFFF;fontSize=10;fontFamily=Arial;fontColor=#FFFFFF;align=center;" parent="1" vertex="1">
|
||||
<mxGeometry x="350" y="250" width="200" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
После Ширина: | Высота: | Размер: 63 KiB |
@@ -0,0 +1,61 @@
|
||||
<mxfile host="65bd71144e" scale="1" border="20">
|
||||
<diagram name="Host-Device Data Flow" id="host-device-flow">
|
||||
<mxGraphModel dx="739" dy="990" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="600" pageHeight="300" background="#5E5B61" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="title" value="Host-Device Data Flow" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=18;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="10" width="200" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="host-box" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#585556;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" vertex="1">
|
||||
<mxGeometry x="50" y="70" width="150" height="180" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="host-label" value="Host (CPU)" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=16;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="75" y="80" width="100" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="device-box" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" vertex="1">
|
||||
<mxGeometry x="400" y="70" width="150" height="180" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="device-label" value="Device (GPU)" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=16;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="425" y="80" width="100" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="arrow-1" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="200" y="120" as="sourcePoint"/>
|
||||
<mxPoint x="400" y="120" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="label-1" value="1. Initialize" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=12;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="250" y="100" width="100" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="arrow-2" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="200" y="160" as="sourcePoint"/>
|
||||
<mxPoint x="400" y="160" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="label-2" value="2. Transfer Data" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=12;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="250" y="140" width="100" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="arrow-3" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="200" y="200" as="sourcePoint"/>
|
||||
<mxPoint x="400" y="200" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="label-3" value="3. Execute Kernel" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=12;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="250" y="180" width="100" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="arrow-4" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="400" y="240" as="sourcePoint"/>
|
||||
<mxPoint x="200" y="240" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="label-4" value="4. Return Results" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=12;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="250" y="220" width="100" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
После Ширина: | Высота: | Размер: 9.7 KiB |
@@ -0,0 +1,237 @@
|
||||
<mxfile host="65bd71144e" scale="1" border="20">
|
||||
<diagram name="Memory Access Patterns" id="memory-patterns">
|
||||
<mxGraphModel dx="739" dy="990" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="600" pageHeight="300" background="#5E5B61" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="title" value="Memory Access Patterns" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=18;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="10" width="200" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="uncoalesced-title" value="Uncoalesced Access" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=14;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="75" y="40" width="150" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="uncoalesced-threads" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#585556;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" vertex="1">
|
||||
<mxGeometry x="50" y="80" width="200" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="uncoalesced-threads-title" value="Threads" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=12;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="100" y="62" width="100" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="uncoalesced-div1" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="100" y="80" as="sourcePoint"/>
|
||||
<mxPoint x="100" y="160" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="uncoalesced-div2" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="150" y="80" as="sourcePoint"/>
|
||||
<mxPoint x="150" y="160" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="uncoalesced-div3" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="200" y="80" as="sourcePoint"/>
|
||||
<mxPoint x="200" y="160" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="uncoalesced-memory" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" vertex="1">
|
||||
<mxGeometry x="50" y="200" width="200" height="40" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="uncoalesced-memory-title" value="Memory" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=12;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="100" y="240" width="100" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="uncoalesced-mem-div1" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="100" y="200" as="sourcePoint"/>
|
||||
<mxPoint x="100" y="240" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="uncoalesced-mem-div2" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="150" y="200" as="sourcePoint"/>
|
||||
<mxPoint x="150" y="240" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="uncoalesced-mem-div3" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="200" y="200" as="sourcePoint"/>
|
||||
<mxPoint x="200" y="240" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="uncoalesced-arrow1" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="75" y="160" as="sourcePoint"/>
|
||||
<mxPoint x="75" y="200" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="uncoalesced-arrow2" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="125" y="160" as="sourcePoint"/>
|
||||
<mxPoint x="175" y="200" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="uncoalesced-arrow3" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="175" y="160" as="sourcePoint"/>
|
||||
<mxPoint x="125" y="200" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="coalesced-title" value="Coalesced Access" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=14;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="375" y="40" width="150" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="coalesced-threads" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#585556;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" vertex="1">
|
||||
<mxGeometry x="350" y="80" width="200" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="coalesced-threads-title" value="Threads" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=12;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="400" y="62" width="100" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="coalesced-div1" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="400" y="80" as="sourcePoint"/>
|
||||
<mxPoint x="400" y="160" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="coalesced-div2" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="450" y="79" as="sourcePoint"/>
|
||||
<mxPoint x="450" y="159" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="coalesced-div3" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="500" y="80" as="sourcePoint"/>
|
||||
<mxPoint x="500" y="160" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="coalesced-memory" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" vertex="1">
|
||||
<mxGeometry x="350" y="200" width="200" height="40" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="coalesced-memory-title" value="Memory" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=12;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="400" y="240" width="100" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="coalesced-mem-div1" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="400" y="200" as="sourcePoint"/>
|
||||
<mxPoint x="400" y="240" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="coalesced-mem-div2" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="450" y="200" as="sourcePoint"/>
|
||||
<mxPoint x="450" y="240" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="coalesced-mem-div3" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="500" y="200" as="sourcePoint"/>
|
||||
<mxPoint x="500" y="240" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="coalesced-arrow1" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="375" y="160" as="sourcePoint"/>
|
||||
<mxPoint x="375" y="200" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="coalesced-arrow2" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="425" y="160" as="sourcePoint"/>
|
||||
<mxPoint x="425" y="200" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="coalesced-arrow3" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="475" y="160" as="sourcePoint"/>
|
||||
<mxPoint x="475" y="200" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="coalesced-arrow4" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="525" y="160" as="sourcePoint"/>
|
||||
<mxPoint x="525" y="200" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<UserObject label="0" placeholders="1" name="Variable" id="2">
|
||||
<mxCell style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontColor=light-dark(#FFFFFF,#121212);" parent="1" vertex="1">
|
||||
<mxGeometry x="65" y="110" width="20" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
</UserObject>
|
||||
<UserObject label="..." placeholders="1" name="Variable" id="3">
|
||||
<mxCell style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontColor=light-dark(#FFFFFF,#121212);" parent="1" vertex="1">
|
||||
<mxGeometry x="115" y="110" width="20" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
</UserObject>
|
||||
<UserObject label="..." placeholders="1" name="Variable" id="4">
|
||||
<mxCell style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontColor=light-dark(#FFFFFF,#121212);" parent="1" vertex="1">
|
||||
<mxGeometry x="165" y="110" width="20" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
</UserObject>
|
||||
<UserObject label="63" placeholders="1" name="Variable" id="5">
|
||||
<mxCell style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontColor=light-dark(#FFFFFF,#121212);" parent="1" vertex="1">
|
||||
<mxGeometry x="215" y="110" width="20" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
</UserObject>
|
||||
<UserObject label="0" placeholders="1" name="Variable" id="6">
|
||||
<mxCell style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontColor=light-dark(#FFFFFF,#121212);" parent="1" vertex="1">
|
||||
<mxGeometry x="365" y="110" width="20" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
</UserObject>
|
||||
<UserObject label="..." placeholders="1" name="Variable" id="7">
|
||||
<mxCell style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontColor=light-dark(#FFFFFF,#121212);" parent="1" vertex="1">
|
||||
<mxGeometry x="415" y="110" width="20" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
</UserObject>
|
||||
<UserObject label="..." placeholders="1" name="Variable" id="8">
|
||||
<mxCell style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontColor=light-dark(#FFFFFF,#121212);" parent="1" vertex="1">
|
||||
<mxGeometry x="465" y="110" width="20" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
</UserObject>
|
||||
<UserObject label="63" placeholders="1" name="Variable" id="9">
|
||||
<mxCell style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontColor=light-dark(#FFFFFF,#121212);" parent="1" vertex="1">
|
||||
<mxGeometry x="515" y="110" width="20" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
</UserObject>
|
||||
<UserObject label="0" placeholders="1" name="Variable" id="10">
|
||||
<mxCell style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontColor=light-dark(#FFFFFF,#121212);" parent="1" vertex="1">
|
||||
<mxGeometry x="65" y="210" width="20" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
</UserObject>
|
||||
<UserObject label="..." placeholders="1" name="Variable" id="11">
|
||||
<mxCell style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontColor=light-dark(#FFFFFF,#121212);" parent="1" vertex="1">
|
||||
<mxGeometry x="115" y="210" width="20" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
</UserObject>
|
||||
<UserObject label="..." placeholders="1" name="Variable" id="12">
|
||||
<mxCell style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontColor=light-dark(#FFFFFF,#121212);" parent="1" vertex="1">
|
||||
<mxGeometry x="165" y="210" width="20" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
</UserObject>
|
||||
<UserObject label="63" placeholders="1" name="Variable" id="13">
|
||||
<mxCell style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontColor=light-dark(#FFFFFF,#121212);" parent="1" vertex="1">
|
||||
<mxGeometry x="215" y="210" width="20" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
</UserObject>
|
||||
<UserObject label="0" placeholders="1" name="Variable" id="14">
|
||||
<mxCell style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontColor=light-dark(#FFFFFF,#121212);" parent="1" vertex="1">
|
||||
<mxGeometry x="365" y="210" width="20" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
</UserObject>
|
||||
<UserObject label="..." placeholders="1" name="Variable" id="15">
|
||||
<mxCell style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontColor=light-dark(#FFFFFF,#121212);" parent="1" vertex="1">
|
||||
<mxGeometry x="415" y="210" width="20" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
</UserObject>
|
||||
<UserObject label="..." placeholders="1" name="Variable" id="16">
|
||||
<mxCell style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontColor=light-dark(#FFFFFF,#121212);" parent="1" vertex="1">
|
||||
<mxGeometry x="465" y="210" width="20" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
</UserObject>
|
||||
<UserObject label="63" placeholders="1" name="Variable" id="17">
|
||||
<mxCell style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontColor=light-dark(#FFFFFF,#121212);" parent="1" vertex="1">
|
||||
<mxGeometry x="515" y="210" width="20" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
</UserObject>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
После Ширина: | Высота: | Размер: 29 KiB |
@@ -0,0 +1,400 @@
|
||||
<mxfile host="65bd71144e">
|
||||
<diagram id="zBbb_w2fufU70cdOGtND" name="1 oldal">
|
||||
<mxGraphModel dx="755" dy="996" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="660" pageHeight="610" background="none" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="5927" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#5E5B61;fontColor=#FFFFFF;strokeColor=none;spacing=0;" parent="1" vertex="1">
|
||||
<mxGeometry y="20" width="610" height="320" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5928" value="Grid" style="text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=klavika;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="275" y="20" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5879" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="310" y="60" width="280" height="220" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5835" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="60" width="280" height="220" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5836" value="<font face="Klavika" style="font-size: 17px;">Block</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="130" y="60" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5837" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#523E43;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="30" y="90" width="260" height="120" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5838" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="40" y="120" width="110" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5839" value="<span style="color: rgba(0, 0, 0, 0); font-family: monospace; font-size: 0px; text-align: start;">%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22%26lt%3Bfont%20face%3D%26quot%3BKlavika%26quot%3B%20style%3D%26quot%3Bfont-size%3A%2017px%3B%26quot%3B%26gt%3BCluster%20shared%26lt%3B%2Ffont%26gt%3B%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontSize%3D17%3BfontColor%3D%23FFFFFF%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%221007.5%22%20y%3D%22150%22%20width%3D%22115%22%20height%3D%2230%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E</span>" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#585556;fontColor=#FFFFFF;strokeColor=none;container=0;" parent="5838" vertex="1">
|
||||
<mxGeometry width="110" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5840" value="Warp" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;container=0;" parent="5838" vertex="1">
|
||||
<mxGeometry x="18.333333333333332" width="73.33333333333333" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5841" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5838" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="12.051111111111092" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="12.051111111111092" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5842" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5838" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="24.273333333333454" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="24.273333333333454" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5843" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5838" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="36.4955555555555" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="36.4955555555555" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5844" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5838" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="48.71777777777786" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="48.71777777777786" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5845" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5838" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="60.94000000000001" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="60.94000000000001" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5846" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5838" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="73.16222222222237" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="73.16222222222237" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5847" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5838" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="85.38444444444443" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="85.38444444444443" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5848" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5838" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="97.60666666666678" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="97.60666666666678" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5849" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5838" vertex="1">
|
||||
<mxGeometry x="6.416666666666666" y="27" width="4.583333333333333" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5850" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5838" vertex="1">
|
||||
<mxGeometry x="18.333333333333332" y="27" width="4.583333333333333" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5851" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5838" vertex="1">
|
||||
<mxGeometry x="30.25" y="27" width="4.583333333333333" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5852" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5838" vertex="1">
|
||||
<mxGeometry x="42.166666666666664" y="27" width="4.583333333333333" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5853" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5838" vertex="1">
|
||||
<mxGeometry x="55" y="27" width="4.583333333333333" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5854" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5838" vertex="1">
|
||||
<mxGeometry x="66.91666666666666" y="27" width="4.583333333333333" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5855" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5838" vertex="1">
|
||||
<mxGeometry x="78.83333333333333" y="27" width="4.583333333333333" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5856" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5838" vertex="1">
|
||||
<mxGeometry x="90.75" y="27" width="4.583333333333333" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5857" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="160" y="120" width="120" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5858" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#585556;fontColor=#FFFFFF;strokeColor=none;container=0;" parent="5857" vertex="1">
|
||||
<mxGeometry width="120" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5859" value="Warp" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;container=0;" parent="5857" vertex="1">
|
||||
<mxGeometry x="20" width="80" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5860" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5857" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="13.146666666666647" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="13.146666666666647" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5861" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5857" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="26.480000000000132" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="26.480000000000132" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5862" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5857" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="39.813333333333276" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="39.813333333333276" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5863" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5857" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="53.14666666666676" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="53.14666666666676" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5864" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5857" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="66.48000000000002" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="66.48000000000002" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5865" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5857" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="79.8133333333335" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="79.8133333333335" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5866" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5857" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="93.14666666666665" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="93.14666666666665" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5867" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5857" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="106.48000000000013" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="106.48000000000013" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5868" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5857" vertex="1">
|
||||
<mxGeometry x="7" y="27" width="5" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5869" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5857" vertex="1">
|
||||
<mxGeometry x="20" y="27" width="5" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5870" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5857" vertex="1">
|
||||
<mxGeometry x="33" y="27" width="5" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5871" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5857" vertex="1">
|
||||
<mxGeometry x="46" y="27" width="5" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5872" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5857" vertex="1">
|
||||
<mxGeometry x="60" y="27" width="5" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5873" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5857" vertex="1">
|
||||
<mxGeometry x="73" y="27" width="5" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5874" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5857" vertex="1">
|
||||
<mxGeometry x="86" y="27" width="5" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5875" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5857" vertex="1">
|
||||
<mxGeometry x="99" y="27" width="5" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5878" value="Local" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;container=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="120" y="90" width="80" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5876" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#9C2A44;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="40" y="230" width="240" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5877" value="<font face="Klavika" style="font-size: 17px;">Shared</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="130" y="230" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5880" value="<font face="Klavika" style="font-size: 17px;">Block</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="420" y="60" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5881" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#523E43;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="320" y="90" width="260" height="120" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5882" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="330" y="120" width="110" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5883" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#585556;fontColor=#FFFFFF;strokeColor=none;container=0;" parent="5882" vertex="1">
|
||||
<mxGeometry width="110" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5884" value="Warp" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;container=0;" parent="5882" vertex="1">
|
||||
<mxGeometry x="18.333333333333332" width="73.33333333333333" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5885" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5882" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="12.051111111111092" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="12.051111111111092" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5886" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5882" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="24.273333333333454" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="24.273333333333454" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5887" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5882" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="36.4955555555555" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="36.4955555555555" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5888" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5882" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="48.71777777777786" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="48.71777777777786" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5889" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5882" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="60.94000000000001" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="60.94000000000001" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5890" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5882" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="73.16222222222237" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="73.16222222222237" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5891" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5882" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="85.38444444444443" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="85.38444444444443" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5892" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5882" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="97.60666666666678" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="97.60666666666678" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5893" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5882" vertex="1">
|
||||
<mxGeometry x="6.416666666666666" y="27" width="4.583333333333333" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5894" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5882" vertex="1">
|
||||
<mxGeometry x="18.333333333333332" y="27" width="4.583333333333333" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5895" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5882" vertex="1">
|
||||
<mxGeometry x="30.25" y="27" width="4.583333333333333" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5896" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5882" vertex="1">
|
||||
<mxGeometry x="42.166666666666664" y="27" width="4.583333333333333" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5897" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5882" vertex="1">
|
||||
<mxGeometry x="55" y="27" width="4.583333333333333" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5898" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5882" vertex="1">
|
||||
<mxGeometry x="66.91666666666666" y="27" width="4.583333333333333" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5899" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5882" vertex="1">
|
||||
<mxGeometry x="78.83333333333333" y="27" width="4.583333333333333" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5900" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5882" vertex="1">
|
||||
<mxGeometry x="90.75" y="27" width="4.583333333333333" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5901" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="450" y="120" width="120" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5902" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#585556;fontColor=#FFFFFF;strokeColor=none;container=0;" parent="5901" vertex="1">
|
||||
<mxGeometry width="120" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5903" value="Warp" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;container=0;" parent="5901" vertex="1">
|
||||
<mxGeometry x="20" width="80" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5904" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5901" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="13.146666666666647" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="13.146666666666647" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5905" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5901" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="26.480000000000132" y="26.5" as="sourcePoint"/>
|
||||
<mxPoint x="26.480000000000132" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5906" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5901" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="39.813333333333276" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="39.813333333333276" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5907" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5901" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="53.14666666666676" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="53.14666666666676" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5908" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5901" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="66.48000000000002" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="66.48000000000002" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5909" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5901" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="79.8133333333335" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="79.8133333333335" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5910" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5901" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="93.14666666666665" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="93.14666666666665" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5911" value="" style="endArrow=classic;html=1;dashed=1;strokeColor=#FFFFFF;fontColor=#FFFFFF;" parent="5901" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="106.48000000000013" y="26.500000000000057" as="sourcePoint"/>
|
||||
<mxPoint x="106.48000000000013" y="73.5" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5912" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5901" vertex="1">
|
||||
<mxGeometry x="7" y="27" width="5" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5913" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5901" vertex="1">
|
||||
<mxGeometry x="20" y="27" width="5" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5914" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5901" vertex="1">
|
||||
<mxGeometry x="33" y="27" width="5" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5915" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5901" vertex="1">
|
||||
<mxGeometry x="46" y="27" width="5" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5916" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5901" vertex="1">
|
||||
<mxGeometry x="60" y="27" width="5" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5917" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5901" vertex="1">
|
||||
<mxGeometry x="73" y="27" width="5" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5918" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5901" vertex="1">
|
||||
<mxGeometry x="86" y="27" width="5" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5919" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=none;fillColor=#523E43;" parent="5901" vertex="1">
|
||||
<mxGeometry x="99" y="27" width="5" height="37" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5920" value="Local" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Klavika;fontSize=17;fontColor=#FFFFFF;container=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="410" y="90" width="80" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5923" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#9C2A44;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="330" y="230" width="240" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5924" value="<font face="Klavika" style="font-size: 17px;">Shared</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="420" y="230" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5930" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#262626;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="290" width="590" height="40" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5940" value="<font face="Klavika" style="font-size: 17px;">Global</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="392.5" y="295" width="115" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5941" value="<span style="color: rgba(0, 0, 0, 0); font-family: monospace; font-size: 0px; text-align: start;">%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22%26lt%3Bfont%20face%3D%26quot%3BKlavika%26quot%3B%20style%3D%26quot%3Bfont-size%3A%2017px%3B%26quot%3B%26gt%3BCluster%20shared%26lt%3B%2Ffont%26gt%3B%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontSize%3D17%3BfontColor%3D%23FFFFFF%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%221007.5%22%20y%3D%22150%22%20width%3D%22115%22%20height%3D%2230%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E</span>" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#585556;fontColor=#FFFFFF;strokeColor=none;container=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="20" y="295" width="90" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5942" value="<font face="Klavika" style="font-size: 17px;">Constant</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="30" y="295" width="70" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5943" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#9C2A44;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="120" y="295" width="110" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5944" value="<font face="Klavika" style="font-size: 17px;">Texture</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="140" y="295" width="70" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5945" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#9C2A44;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="240" y="295" width="110" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5946" value="<font face="Klavika" style="font-size: 17px;">Surface</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="260" y="295" width="70" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
После Ширина: | Высота: | Размер: 34 KiB |
@@ -0,0 +1,64 @@
|
||||
<mxfile host="65bd71144e" scale="1" border="20">
|
||||
<diagram name="Multi-GPU Workload Distribution" id="multi-gpu">
|
||||
<mxGraphModel dx="739" dy="990" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="600" pageHeight="300" background="#5E5B61" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="title" value="Multi-GPU Workload Distribution" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=18;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="125" y="10" width="300" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="host-cpu" value="Host CPU" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#585556;strokeColor=#FFFFFF;strokeWidth=2;fontSize=14;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="225" y="60" width="100" height="60" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu0" value="GPU 0" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;strokeWidth=2;fontSize=14;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="25" y="180" width="100" height="60" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu1" value="GPU 1" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;strokeWidth=2;fontSize=14;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="175" y="180" width="100" height="60" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu2" value="GPU 2" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;strokeWidth=2;fontSize=14;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="325" y="180" width="100" height="60" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="gpu3" value="GPU 3" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;strokeWidth=2;fontSize=14;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="475" y="180" width="100" height="60" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="arrow0" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="275" y="120" as="sourcePoint"/>
|
||||
<mxPoint x="75" y="180" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="arrow1" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="275" y="120" as="sourcePoint"/>
|
||||
<mxPoint x="225" y="180" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="arrow2" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="275" y="120" as="sourcePoint"/>
|
||||
<mxPoint x="375" y="180" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="arrow3" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="275" y="120" as="sourcePoint"/>
|
||||
<mxPoint x="525" y="180" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="label0" value="25%" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=12;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="45" y="250" width="60" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="label1" value="25%" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=12;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="195" y="250" width="60" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="label2" value="25%" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=12;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="345" y="250" width="60" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="label3" value="25%" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=12;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="495" y="250" width="60" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
После Ширина: | Высота: | Размер: 12 KiB |
|
После Ширина: | Высота: | Размер: 450 KiB |
@@ -0,0 +1,124 @@
|
||||
<mxfile host="65bd71144e" scale="1" border="20">
|
||||
<diagram name="SIMT Execution Model" id="simt-execution">
|
||||
<mxGraphModel dx="739" dy="990" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="600" pageHeight="300" background="#5E5B61" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="title" value="SIMT Execution Model" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=18;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="10" width="200" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="instruction" value="a[i] = b[i] + c[i]" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;strokeWidth=2;fontFamily=Arial;fontSize=14;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="50" width="200" height="40" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="arrow1" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="300" y="90" as="sourcePoint"/>
|
||||
<mxPoint x="110" y="140" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="arrow2" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="300" y="90" as="sourcePoint"/>
|
||||
<mxPoint x="240" y="140" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="arrow3" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="300" y="90" as="sourcePoint"/>
|
||||
<mxPoint x="370" y="140" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="arrow4" value="" style="endArrow=classic;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="300" y="90" as="sourcePoint"/>
|
||||
<mxPoint x="500" y="140" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="lane0" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#585556;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" vertex="1">
|
||||
<mxGeometry x="50" y="140" width="120" height="120" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="lane0-title" value="Thread 0" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=12;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="80" y="150" width="60" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="lane0-line" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=1;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="50" y="170" as="sourcePoint"/>
|
||||
<mxPoint x="170" y="170" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="lane0-b" value="b[0] = 5" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=10;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="80" y="180" width="60" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="lane0-c" value="c[0] = 3" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=10;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="80" y="200" width="60" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="lane0-a" value="a[0] = 8" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=10;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="80" y="230" width="60" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="lane1" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#585556;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" vertex="1">
|
||||
<mxGeometry x="180" y="140" width="120" height="120" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="lane1-title" value="Thread 1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=12;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="210" y="150" width="60" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="lane1-line" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=1;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="180" y="170" as="sourcePoint"/>
|
||||
<mxPoint x="300" y="170" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="lane1-b" value="b[1] = 2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=10;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="210" y="180" width="60" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="lane1-c" value="c[1] = 4" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=10;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="210" y="200" width="60" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="lane1-a" value="a[1] = 6" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=10;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="210" y="230" width="60" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="lane2" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#585556;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" vertex="1">
|
||||
<mxGeometry x="310" y="140" width="120" height="120" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="lane2-title" value="Thread 2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=12;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="340" y="150" width="60" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="lane2-line" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=1;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="310" y="170" as="sourcePoint"/>
|
||||
<mxPoint x="430" y="170" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="lane2-b" value="b[2] = 7" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=10;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="340" y="180" width="60" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="lane2-c" value="c[2] = 1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=10;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="340" y="200" width="60" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="lane2-a" value="a[2] = 8" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=10;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="340" y="230" width="60" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="lane3" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#585556;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" vertex="1">
|
||||
<mxGeometry x="440" y="140" width="120" height="120" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="lane3-title" value="Thread 3" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=12;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="470" y="150" width="60" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="lane3-line" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=1;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="440" y="170" as="sourcePoint"/>
|
||||
<mxPoint x="560" y="170" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="lane3-b" value="b[3] = 3" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=10;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="470" y="180" width="60" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="lane3-c" value="c[3] = 5" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=10;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="470" y="200" width="60" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="lane3-a" value="a[3] = 8" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=10;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="470" y="230" width="60" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
После Ширина: | Высота: | Размер: 21 KiB |
@@ -0,0 +1,97 @@
|
||||
<mxfile host="65bd71144e">
|
||||
<diagram name="Stream and Event Workflow" id="stream-workflow">
|
||||
<mxGraphModel dx="616" dy="825" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="600" pageHeight="300" background="#5E5B61" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="title" value="Stream and Event Workflow" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=18;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="10" width="200" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="timeline1" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="80" y="100" as="sourcePoint"/>
|
||||
<mxPoint x="550" y="100" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="timeline2" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="80" y="180" as="sourcePoint"/>
|
||||
<mxPoint x="550" y="180" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="timeline3" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="80" y="260" as="sourcePoint"/>
|
||||
<mxPoint x="550" y="260" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="stream1-label" value="Stream 1" style="text;html=1;strokeColor=none;fillColor=none;align=right;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=14;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="90" width="60" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="stream2-label" value="Stream 2" style="text;html=1;strokeColor=none;fillColor=none;align=right;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=14;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="170" width="60" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="stream3-label" value="Stream 3" style="text;html=1;strokeColor=none;fillColor=none;align=right;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=14;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="250" width="60" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="op1-1" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" vertex="1">
|
||||
<mxGeometry x="90" y="80" width="100" height="40" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="op1-2" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" vertex="1">
|
||||
<mxGeometry x="210" y="80" width="150" height="40" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="op1-3" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" vertex="1">
|
||||
<mxGeometry x="380" y="80" width="80" height="40" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="op2-1" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" vertex="1">
|
||||
<mxGeometry x="150" y="160" width="120" height="40" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="op2-2" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" vertex="1">
|
||||
<mxGeometry x="290" y="160" width="100" height="40" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="op3-1" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" vertex="1">
|
||||
<mxGeometry x="230" y="240" width="140" height="40" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="op3-2" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;strokeWidth=2;" parent="1" vertex="1">
|
||||
<mxGeometry x="410" y="240" width="120" height="40" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="event1" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#FFFFFF;strokeColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="375" y="95" width="10" height="10" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="event2" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#FFFFFF;strokeColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="285" y="175" width="10" height="10" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="event3" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#FFFFFF;strokeColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="405" y="255" width="10" height="10" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="dep1" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;dashed=1;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="380" y="100" as="sourcePoint"/>
|
||||
<mxPoint x="290" y="180" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="dep2" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;dashed=1;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="290" y="180" as="sourcePoint"/>
|
||||
<mxPoint x="410" y="260" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="legend-op" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#C23555;strokeColor=#FFFFFF;strokeWidth=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="450" y="30" width="20" height="10" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="legend-op-text" value="Operation" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=10;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="480" y="28" width="60" height="12" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="legend-event" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#FFFFFF;strokeColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="455" y="46" width="10" height="10" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="legend-event-text" value="Event" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=10;fontFamily=Arial;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="480" y="46" width="60" height="12" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;strokeColor=#FFFFFF;strokeWidth=2;" vertex="1" parent="1">
|
||||
<mxGeometry x="2" y="1" width="564" height="296" as="geometry"/>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
После Ширина: | Высота: | Размер: 9.5 KiB |
|
После Ширина: | Высота: | Размер: 477 KiB |
@@ -0,0 +1,157 @@
|
||||
<mxfile host="65bd71144e">
|
||||
<diagram id="zBbb_w2fufU70cdOGtND" name="1 oldal">
|
||||
<mxGraphModel dx="1547" dy="1302" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="660" pageHeight="610" background="none" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="6033" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#5E5B61;fontColor=#FFFFFF;strokeColor=none;spacing=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="110" y="-320" width="480" height="490" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5981" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="130" y="60" width="210" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5982" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#333333;fontColor=#FFFFFF;strokeColor=none;" parent="5981" vertex="1">
|
||||
<mxGeometry width="210" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5983" value="" style="group" parent="5981" vertex="1" connectable="0">
|
||||
<mxGeometry x="7.7419872652362365" y="8" width="192.50000000000003" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5984" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#60a917;fontColor=#ffffff;strokeColor=#2D7600;" parent="5983" vertex="1">
|
||||
<mxGeometry y="2" width="192.50000000000003" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5985" value="<div>NVIDIA runtime</div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="5983" vertex="1">
|
||||
<mxGeometry x="11.998194444444442" y="13.01" width="168.50166666666664" height="18.99" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5986" value="<font style="">NVIDIA Platform</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="5981" vertex="1">
|
||||
<mxGeometry x="40" y="63" width="130" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5987" value="" style="endArrow=classic;startArrow=none;html=1;rounded=0;strokeWidth=2;startFill=0;strokeColor=#FFFFFF;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="315" y="45" as="sourcePoint"/>
|
||||
<mxPoint x="315" y="70" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5988" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#9C2A44;fontColor=#FFFFFF;strokeColor=#4c1523;strokeWidth=5;" parent="1" vertex="1">
|
||||
<mxGeometry x="300" y="-17" width="260" height="60" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5989" value="<font style="font-size: 14px;" face="Helvetica">HIP</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;strokeWidth=2;" parent="1" vertex="1">
|
||||
<mxGeometry x="300" y="-17" width="260" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5990" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#333333;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="350" y="60" width="210" height="90" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5991" value="" style="group;fillColor=#A50040;fontColor=#ffffff;strokeColor=none;" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="360" y="70" width="192" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5992" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#962744;fontColor=#FFFFFF;strokeColor=none;" parent="5991" vertex="1">
|
||||
<mxGeometry width="192.00000000000003" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5993" value="<div>AMD runtime</div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#ffffff;" parent="5991" vertex="1">
|
||||
<mxGeometry x="8.638736842105262" y="7.497" width="174.72" height="29.996999999999993" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="5994" value="" style="endArrow=classic;startArrow=none;html=1;rounded=0;strokeWidth=2;startFill=0;strokeColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" target="5992" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="456" y="44" as="sourcePoint"/>
|
||||
<mxPoint x="470" y="70" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5995" value="<font face="Helvetica">AMD Platform<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="365" y="123" width="180" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6003" value="" style="endArrow=classic;startArrow=none;html=1;rounded=0;strokeWidth=2;startFill=0;strokeColor=#FFFFFF;exitX=0.25;exitY=1;exitDx=0;exitDy=0;entryX=0.855;entryY=-0.018;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" target="6000" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="309.5" y="-104" as="sourcePoint"/>
|
||||
<mxPoint x="309.55999999999995" y="-60.975106382978765" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="6004" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#9C2A44;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="274.5" y="-150" width="140" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6005" value="<font face="Helvetica">hipLibrary</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#ffffff;dashed=1;strokeWidth=2;" parent="1" vertex="1">
|
||||
<mxGeometry x="274.5" y="-150" width="140" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6007" value="" style="group;dashed=1;strokeWidth=2;strokeColor=none;" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="360" y="-80" width="140" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6008" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#962744;fontColor=#FFFFFF;strokeColor=none;dashed=1;strokeWidth=2;" parent="6007" vertex="1">
|
||||
<mxGeometry width="140.00000000000003" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6009" value="<div>rocLibrary</div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="6007" vertex="1">
|
||||
<mxGeometry x="6.299078947368418" y="7.497" width="127.39999999999998" height="29.996999999999993" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6010" value="" style="endArrow=classic;startArrow=none;html=1;rounded=0;strokeWidth=2;startFill=0;strokeColor=#FFFFFF;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="386" y="-105" as="sourcePoint"/>
|
||||
<mxPoint x="386" y="-80" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5999" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="190" y="-80" width="140" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6000" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#60a917;fontColor=#ffffff;strokeColor=#2D7600;" parent="5999" vertex="1">
|
||||
<mxGeometry y="-0.005106382978723234" width="140" height="45" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6001" value="<div>cuLibrary</div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="5999" vertex="1">
|
||||
<mxGeometry x="10.019288676236041" y="13.404255319148938" width="119.9667368421052" height="18.18191489361702" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6013" style="edgeStyle=none;html=1;strokeWidth=2;strokeColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" target="5984" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="234" y="-35" as="sourcePoint"/>
|
||||
<mxPoint x="220" y="60" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="6014" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeWidth=2;strokeColor=#FFFFFF;" parent="1" source="6008" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="430" y="-19" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="6025" value="" style="group;strokeColor=none;dashed=1;strokeWidth=2;" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="129.5" y="-290" width="430" height="100" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6023" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#333333;fontColor=#FFFFFF;strokeColor=none;spacing=0;" parent="6025" vertex="1">
|
||||
<mxGeometry width="430" height="100" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6024" value="<div>Application Implementation</div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="6025" vertex="1">
|
||||
<mxGeometry x="97.50999999999999" y="43.93999999999998" width="234.99" height="12.120000000000001" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6026" style="edgeStyle=none;html=1;entryX=0.148;entryY=0.008;entryDx=0;entryDy=0;strokeWidth=2;entryPerimeter=0;strokeColor=#FFFFFF;" parent="1" target="5984" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="166" y="-190" as="sourcePoint"/>
|
||||
<mxPoint x="159.99598908448831" y="-94.12" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="6027" style="edgeStyle=none;html=1;strokeWidth=2;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#FFFFFF;" parent="1" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="260" y="-190" as="sourcePoint"/>
|
||||
<mxPoint x="260" y="-80.00510638297874" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="6029" style="edgeStyle=none;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeWidth=2;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#FFFFFF;" parent="1" source="6023" target="6005" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="320" y="-190" as="sourcePoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="6030" style="edgeStyle=none;html=1;strokeWidth=2;strokeColor=#FFFFFF;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" target="6008" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="452" y="-80" as="targetPoint"/>
|
||||
<mxPoint x="430" y="-190" as="sourcePoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="6031" style="edgeStyle=none;html=1;exitX=0.912;exitY=1.013;exitDx=0;exitDy=0;strokeWidth=2;exitPerimeter=0;strokeColor=#FFFFFF;" parent="1" source="6023" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="520" y="-19" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="6034" value="<div>Application</div>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=17;fontColor=#FFFFFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="232.5" y="-310" width="234.99" height="12.120000000000001" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6035" value="runtime API" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#4F1623;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="310" y="3" width="115" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="6036" value="kernel language" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#4F1623;fontColor=#FFFFFF;strokeColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="437" y="3" width="115" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
После Ширина: | Высота: | Размер: 18 KiB |
@@ -0,0 +1,509 @@
|
||||
"""
|
||||
Copyright (c) 2015-2021 Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
|
||||
"""
|
||||
1. This files uses Python3 to run
|
||||
|
||||
List of device functions:
|
||||
acosf
|
||||
acoshf
|
||||
asinf
|
||||
asinhf
|
||||
atan2f
|
||||
atanf
|
||||
atanhf
|
||||
cbrtf
|
||||
ceilf
|
||||
copysignf
|
||||
cosf
|
||||
coshf
|
||||
cospif
|
||||
cyl_bessel_i0f
|
||||
cyl_bessel_i1f
|
||||
erfcf
|
||||
erfcinvf
|
||||
erfcxf
|
||||
erff
|
||||
erfinvf
|
||||
exp10f
|
||||
exp2f
|
||||
expf
|
||||
expm1f
|
||||
fabsf
|
||||
fdimf
|
||||
fdividef
|
||||
floorf
|
||||
fmaf
|
||||
fmaxf
|
||||
fminf
|
||||
fmodf
|
||||
frexpf
|
||||
hypotf
|
||||
ilogbf
|
||||
isfinite
|
||||
isinf
|
||||
isnan
|
||||
j0f
|
||||
j1f
|
||||
jnf
|
||||
ldexpf
|
||||
lgammaf
|
||||
llrintf
|
||||
llroundf
|
||||
log10f
|
||||
log1pf
|
||||
logbf
|
||||
lrintf
|
||||
lroundf
|
||||
modff
|
||||
nanf
|
||||
nearbyintf
|
||||
nextafterf
|
||||
norm3df
|
||||
norm4df
|
||||
normcdff
|
||||
normcdfinvf
|
||||
normf
|
||||
powf
|
||||
rcbrtf
|
||||
remainderf
|
||||
remquof
|
||||
rhypotf
|
||||
rintf
|
||||
rnorm3df
|
||||
rnorm4df
|
||||
rnormf
|
||||
roundf
|
||||
rsqrtf
|
||||
scalblnf
|
||||
scalbnf
|
||||
signbit
|
||||
sincosf
|
||||
sincospif
|
||||
sinf
|
||||
sinhf
|
||||
sinpif
|
||||
sqrtf
|
||||
tanf
|
||||
tanhf
|
||||
tgammaf
|
||||
truncf
|
||||
y0f
|
||||
y1f
|
||||
ynf
|
||||
acos
|
||||
acosh
|
||||
asin
|
||||
asinh
|
||||
atan
|
||||
atan2
|
||||
atanh
|
||||
cbrt
|
||||
ceil
|
||||
copysign
|
||||
cos
|
||||
cosh
|
||||
cospi
|
||||
cyl_bessel_i0
|
||||
cyl_bessel_i1
|
||||
erf
|
||||
erfc
|
||||
erfcinv
|
||||
erfcx
|
||||
erfinv
|
||||
exp
|
||||
exp10
|
||||
exp2
|
||||
expm1
|
||||
fabs
|
||||
fdim
|
||||
floor
|
||||
fma
|
||||
fmax
|
||||
fmin
|
||||
fmod
|
||||
frexp
|
||||
hypot
|
||||
ilogb
|
||||
isfinite
|
||||
isinf
|
||||
isnan
|
||||
j0
|
||||
j1
|
||||
jn
|
||||
ldexp
|
||||
lgamma
|
||||
llrint
|
||||
llround
|
||||
log
|
||||
log10
|
||||
log1p
|
||||
log2
|
||||
logb
|
||||
lrint
|
||||
lround
|
||||
modf
|
||||
nan
|
||||
nearbyint
|
||||
nextafter
|
||||
norm
|
||||
norm3d
|
||||
norm4d
|
||||
normcdf
|
||||
normcdfinv
|
||||
pow
|
||||
rcbrt
|
||||
remainder
|
||||
remquo
|
||||
rhypot
|
||||
rint
|
||||
rnorm
|
||||
rnorm3d
|
||||
rnorm4d
|
||||
round
|
||||
rsqrt
|
||||
scalbln
|
||||
scalbn
|
||||
signbit
|
||||
sin
|
||||
sincos
|
||||
sincospi
|
||||
sinh
|
||||
sinpi
|
||||
sqrt
|
||||
tan
|
||||
tanh
|
||||
tgamma
|
||||
trunc
|
||||
y0
|
||||
y1
|
||||
yn
|
||||
__cosf
|
||||
__exp10f
|
||||
__expf
|
||||
__fadd_rd
|
||||
__fadd_rn
|
||||
__fadd_ru
|
||||
__fadd_rz
|
||||
__fdiv_rd
|
||||
__fdiv_rn
|
||||
__fdiv_ru
|
||||
__fdiv_rz
|
||||
__fdividef
|
||||
__fmaf_rd
|
||||
__fmaf_rn
|
||||
__fmaf_ru
|
||||
__fmaf_rz
|
||||
__fmul_rd
|
||||
__fmul_rn
|
||||
__fmul_ru
|
||||
__fmul_rz
|
||||
__frcp_rd
|
||||
__frcp_rn
|
||||
__frcp_ru
|
||||
__frcp_rz
|
||||
__frsqrt_rn
|
||||
__fsqrt_rd
|
||||
__fsqrt_rn
|
||||
__fsqrt_ru
|
||||
__fsqrt_rz
|
||||
__fsub_rd
|
||||
__fsub_rn
|
||||
__fsub_ru
|
||||
__log10f
|
||||
__log2f
|
||||
__logf
|
||||
__powf
|
||||
__saturatef
|
||||
__sincosf
|
||||
__sinf
|
||||
__tanf
|
||||
__dadd_rd
|
||||
__dadd_rn
|
||||
__dadd_ru
|
||||
__dadd_rz
|
||||
__ddiv_rd
|
||||
__ddiv_rn
|
||||
__ddiv_ru
|
||||
__ddiv_rz
|
||||
__dmul_rd
|
||||
__dmul_rn
|
||||
__dmul_ru
|
||||
__dmul_rz
|
||||
__drcp_rd
|
||||
__drcp_rn
|
||||
__drcp_ru
|
||||
__drcp_rz
|
||||
__dsqrt_rd
|
||||
__dsqrt_rn
|
||||
__dsqrt_ru
|
||||
__dsqrt_rz
|
||||
__dsub_rd
|
||||
__dsub_rn
|
||||
__dsub_ru
|
||||
__dsub_rz
|
||||
__fma_rd
|
||||
__fma_rn
|
||||
__fma_ru
|
||||
__fma_rz
|
||||
__brev
|
||||
__brevll
|
||||
__byte_perm
|
||||
__clz
|
||||
__clzll
|
||||
__ffs
|
||||
__ffsll
|
||||
__hadd
|
||||
__mul24
|
||||
__mul64hi
|
||||
__mulhi
|
||||
__popc
|
||||
__popcll
|
||||
__rhadd
|
||||
__sad
|
||||
__uhadd
|
||||
__umul24
|
||||
__umul64hi
|
||||
__umulhi
|
||||
__urhadd
|
||||
__usad
|
||||
__double2float_rd
|
||||
__double2float_rn
|
||||
__double2float_ru
|
||||
__double2float_rz
|
||||
__double2hiint
|
||||
__double2int_rd
|
||||
__double2int_rn
|
||||
__double2int_ru
|
||||
__double2int_rz
|
||||
__double2ll_rd
|
||||
__double2ll_rn
|
||||
__double2ll_ru
|
||||
__double2ll_rz
|
||||
__double2loint
|
||||
__double2uint_rd
|
||||
__double2uint_rn
|
||||
__double2uint_ru
|
||||
__double2uint_rz
|
||||
__double2ull_rd
|
||||
__double2ull_rn
|
||||
__double2ull_ru
|
||||
__double2ull_rz
|
||||
__double_as_longlong
|
||||
__float2half_rn
|
||||
__half2float
|
||||
__float2half_rn
|
||||
__half2float
|
||||
__float2int_rd
|
||||
__float2int_rn
|
||||
__float2int_ru
|
||||
__float2int_rz
|
||||
__float2ll_rd
|
||||
__float2ll_rn
|
||||
__float2ll_ru
|
||||
__float2ll_rz
|
||||
__float2uint_rd
|
||||
__float2uint_rn
|
||||
__float2uint_ru
|
||||
__float2uint_rz
|
||||
__float2ull_rd
|
||||
__float2ull_rn
|
||||
__float2ull_ru
|
||||
__float2ull_rz
|
||||
__float_as_int
|
||||
__float_as_uint
|
||||
__hiloint2double
|
||||
__int2double_rn
|
||||
__int2float_rd
|
||||
__int2float_rn
|
||||
__int2float_ru
|
||||
__int2float_rz
|
||||
__int_as_float
|
||||
__ll2double_rd
|
||||
__ll2double_rn
|
||||
__ll2double_ru
|
||||
__ll2double_rz
|
||||
__ll2float_rd
|
||||
__ll2float_rn
|
||||
__ll2float_ru
|
||||
__ll2float_rz
|
||||
__longlong_as_double
|
||||
__uint2double_rn
|
||||
__uint2float_rd
|
||||
__uint2float_rn
|
||||
__uint2float_ru
|
||||
__uint2float_rz
|
||||
__uint_as_float
|
||||
__ull2double_rd
|
||||
__ull2double_rn
|
||||
__ull2double_ru
|
||||
__ull2double_rz
|
||||
__ull2float_rd
|
||||
__ull2float_rn
|
||||
__ull2float_ru
|
||||
__ull2float_rz
|
||||
__heq
|
||||
__hge
|
||||
__hgt
|
||||
__hisinf
|
||||
__hisnan
|
||||
__hle
|
||||
__hlt
|
||||
__hne
|
||||
__hbeq2
|
||||
__hbge2
|
||||
__hbgt2
|
||||
__hble2
|
||||
__hblt2
|
||||
__hbne2
|
||||
__heq2
|
||||
__hge2
|
||||
__hgt2
|
||||
__hisnan2
|
||||
__hle2
|
||||
__hlt2
|
||||
__hne2
|
||||
__float22half2_rn
|
||||
__float2half
|
||||
__float2half2_rn
|
||||
__float2half_rd
|
||||
__float2half_rn
|
||||
__float2half_ru
|
||||
__float2half_rz
|
||||
__floats2half2_rn
|
||||
__half22float2
|
||||
__half2float
|
||||
half2half2
|
||||
__half2int_rd
|
||||
__half2int_rn
|
||||
__half2int_ru
|
||||
__half2int_rz
|
||||
__half2ll_rd
|
||||
__half2ll_rn
|
||||
__half2ll_ru
|
||||
__half2ll_rz
|
||||
__half2short_rd
|
||||
__half2short_rn
|
||||
__half2short_ru
|
||||
__half2short_rz
|
||||
__half2uint_rd
|
||||
__half2uint_rn
|
||||
__half2uint_ru
|
||||
__half2uint_rz
|
||||
__half2ull_rd
|
||||
__half2ull_rn
|
||||
__half2ull_ru
|
||||
__half2ull_rz
|
||||
__half2ushort_rd
|
||||
__half2ushort_rn
|
||||
__half2ushort_ru
|
||||
__half2ushort_rz
|
||||
__half_as_short
|
||||
__half_as_ushort
|
||||
__halves2half2
|
||||
__high2float
|
||||
__high2half
|
||||
__high2half2
|
||||
__highs2half2
|
||||
__int2half_rd
|
||||
__int2half_rn
|
||||
__int2half_ru
|
||||
__int2half_rz
|
||||
__ll2half_rd
|
||||
__ll2half_rn
|
||||
__ll2half_ru
|
||||
__ll2half_rz
|
||||
__low2float
|
||||
__low2half
|
||||
__low2half2
|
||||
__low2half2
|
||||
__lowhigh2highlow
|
||||
__lows2half2
|
||||
__short2half_rd
|
||||
__short2half_rn
|
||||
__short2half_ru
|
||||
__short2half_rz
|
||||
__uint2half_rd
|
||||
__uint2half_rn
|
||||
__uint2half_ru
|
||||
__uint2half_rz
|
||||
__ull2half_rd
|
||||
__ull2half_rn
|
||||
__ull2half_ru
|
||||
__ull2half_rz
|
||||
__ushort2half_rd
|
||||
__ushort2half_rn
|
||||
__ushort2half_ru
|
||||
__ushort2half_rz
|
||||
__ushort_as_half
|
||||
"""
|
||||
# The dictionary is to place description of each device function. Expand it to all the device functions
|
||||
deviceFuncDesc = {'acosf': "This function returns floating point of arc cosine from a floating point input"}
|
||||
|
||||
fnames = ["../../include/hip/amd_detail/math_functions.h","../../include/hip/amd_detail/device_functions.h","../../include/hip/amd_detail/hip_fp16.h"]
|
||||
markdownFileName = "./hip-math-api.md"
|
||||
|
||||
preamble = "# HIP MATH APIs Documentation \n"+\
|
||||
"HIP supports most of the device functions supported by CUDA. Way to find the unsupported one is to search for the function and check its description\n" + \
|
||||
"Note: This document is not human generated. Any changes to this file will be discarded. Please make changes to Python3 script docs/markdown/device_md_gen.py\n\n" + \
|
||||
"## For Developers \n" + \
|
||||
"If you add or fixed a device function, make sure to add a signature of the function and definition later.\n" + \
|
||||
"For example, if you want to add `__device__ float __dotf(float4, float4)`, which does a dot product on 4 float vector components \n" + \
|
||||
"The way to add to the header is, \n" + \
|
||||
"```cpp \n" + \
|
||||
"__device__ static float __dotf(float4, float4); \n" + \
|
||||
"/*Way down in the file....*/\n" + \
|
||||
"__device__ static inline float __dotf(float4 x, float4 y) { \n" + \
|
||||
" /*implementation*/\n}\n" + \
|
||||
"```\n\n" + \
|
||||
"This helps python script to add the device function newly declared into markdown documentation (as it looks at functions with `;` at the end and `__device__` at the beginning)\n\n" + \
|
||||
"The next step would be to add Description to `deviceFuncDesc` dictionary in python script.\n" + \
|
||||
"From the above example, it can be writtern as,\n`deviceFuncDesc['__dotf'] = 'This functions takes 2 4 component float vector and outputs dot product across them'`\n\n"
|
||||
|
||||
def generateSnippet(name, description, signature):
|
||||
return "### " + name + "\n" + \
|
||||
"```cpp \n" + signature + "\n```\n" + \
|
||||
"**Description:** " + description + "\n\n\n"
|
||||
|
||||
def getName(line):
|
||||
l1 = line.split('(')
|
||||
l2 = l1[0].split(' ')
|
||||
return l2[-1]
|
||||
|
||||
with open(markdownFileName, 'w') as mdfd:
|
||||
mdfd.truncate()
|
||||
mdfd.write(preamble)
|
||||
for fname in fnames:
|
||||
with open(fname) as fd:
|
||||
lines = fd.readlines()
|
||||
for line in lines:
|
||||
if line.find('HIP_FAST_MATH') != -1:
|
||||
break;
|
||||
if line.find('__device__') != -1 and line.find(';') != -1 and line.find('hip') == -1:
|
||||
name = getName(line)
|
||||
if line.find('//') == -1:
|
||||
if name in deviceFuncDesc:
|
||||
mdfd.write(generateSnippet(name, deviceFuncDesc[name], line))
|
||||
else:
|
||||
mdfd.write(generateSnippet(name, "Supported", line))
|
||||
else:
|
||||
mdfd.write(generateSnippet(name, "**NOT Supported**", line))
|
||||
fd.close()
|
||||
mdfd.close()
|
||||
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* @file mainpage.cpp
|
||||
* @brief : DoxyGen Main Page.
|
||||
* @mainpage Heterogeneous-computing Interface for Portability (HIP)
|
||||
* @tableofcontents
|
||||
*
|
||||
* The HIP interface makes it very easy to port existing CUDA apps to run on AMD GPUs,
|
||||
* or to develop new apps that can run on either CUDA or AMD GPUs from a common source base.
|
||||
*
|
||||
* - HIP is very thin and has little or no performance impact over coding directly in CUDA NVCC mode.
|
||||
* - HIP allows developers to use the "best" development environment and tools on each target platform.
|
||||
* - HIP allows coding in a single-source C++ programming language including features such as templates, C++11 lambdas,and more.
|
||||
* - HIPIFY tools automatically convert CUDA sources to HIP.
|
||||
* - Developers can specialize for CUDA or HIP to tune for performance or handle tricky cases with #ifdef.
|
||||
|
||||
* - See the @ref API.
|
||||
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,49 @@
|
||||
/** @page Synchonization
|
||||
* @tableofcontents
|
||||
|
||||
* # Host-synchronous behavior:
|
||||
The following commands are "host-asynchronous" - meaning they do not wait for any preceding commands to complete, and may return control to the host thread before the requested operation completes:
|
||||
|
||||
- Kernel launches (hipLaunchKernel() )
|
||||
- Asynchronous memory copies - any memory copy API which contains "Async", such as hipMemcpyAsync())
|
||||
- Any memory set (for example, hipMemset());
|
||||
- TODO
|
||||
|
||||
"Host-synchronous" commands have the following properties:
|
||||
- wait for all previous commands to complete.
|
||||
- will not return control back to host until the command completes.
|
||||
|
||||
|
||||
The following commands are "host-synchronous".
|
||||
|
||||
- hipMemcpy waits for preceding work in the same stream to complete.
|
||||
|
||||
|
||||
* # Stream synchronization
|
||||
|
||||
|
||||
### Blocking
|
||||
|
||||
The term "blocking" has two meanings in HIP.
|
||||
|
||||
The first refers to synchronization commands (ie hipStreamSynchronize, hipEventSynchronize) that cause the host CPU to wait for GPU activity to complete.
|
||||
These can either use an active where the host CPU spin-waits on the synchronization variable, or can use an interrupt-based scheme where the core is interrupted
|
||||
when the wait completes. The second technique is referred to as "blocking" (ie hipDeviceBlockingSync, hipEventBlockingSync) while the first is referred
|
||||
to as "active". Active can be appropriate for short tasks where latency is critical, but comes at the expense of a CPU core dedicated to monitoring the event.
|
||||
|
||||
### HIP_LAUNCH_BLOCKING (also can use CUDA_LAUNCH_BLOCKING)
|
||||
|
||||
- The following commands become host-synchronous and will not return until the requested command has completed:
|
||||
|
||||
- Kernel launches (hipKernelLaunch).
|
||||
- Memory set commands (hipMemset, hipMemsetAsync).
|
||||
- Memory copy commands (hipMemcpy, hipMemsetAsync).
|
||||
|
||||
Note CUDA_LAUNCH_BLOCKING does add any pre-serialization to the commands and does not affect the concurrent stream behavior. For example,
|
||||
even when CUDA_LAUNCH_BLOCKING is set, kernels or data copy commands launched to separate streams can execute concurrently. Use the NULL
|
||||
stream if additional stream synchronization is desired.
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,10 @@
|
||||
name: RTD
|
||||
channels:
|
||||
- conda-forge
|
||||
- defaults
|
||||
dependencies:
|
||||
- python=3.10
|
||||
- pip
|
||||
- doxygen=1.9.8
|
||||
- pip:
|
||||
- -r ./sphinx/requirements.txt
|
||||
@@ -0,0 +1,59 @@
|
||||
import os
|
||||
import re
|
||||
from docutils.parsers.rst import Directive
|
||||
from docutils.statemachine import StringList
|
||||
|
||||
class TableInclude(Directive):
|
||||
required_arguments = 1
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = True
|
||||
option_spec = {
|
||||
'table': str
|
||||
}
|
||||
|
||||
def run(self):
|
||||
# Get the file path from the first argument
|
||||
file_path = self.arguments[0]
|
||||
|
||||
# Get the environment to resolve the full path
|
||||
env = self.state.document.settings.env
|
||||
src_dir = os.path.abspath(env.srcdir)
|
||||
full_file_path = os.path.join(src_dir, file_path)
|
||||
|
||||
# Check if the file exists
|
||||
if not os.path.exists(full_file_path):
|
||||
raise self.error(f"RST file {full_file_path} does not exist.")
|
||||
|
||||
# Read the entire file content
|
||||
with open(full_file_path, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
|
||||
# Find all tables with named targets
|
||||
table_pattern = r'(?:^\.\.\ _(.+?):\n)(.. list-table::.*?(?:\n\s*\*\s*-.*?)+)(?=\n\n|\Z)'
|
||||
table_matches = list(re.finditer(table_pattern, content, re.MULTILINE | re.DOTALL))
|
||||
|
||||
# Get the specific table name from options
|
||||
table_name = self.options.get('table')
|
||||
|
||||
# If no table specified, merge compatible tables
|
||||
if not table_name:
|
||||
raise self.error("The ':table:' option is required to specify which table to include.")
|
||||
|
||||
# Find the specific table
|
||||
matching_tables = [
|
||||
match for match in table_matches
|
||||
if match.group(1).strip() == table_name
|
||||
]
|
||||
|
||||
if not matching_tables:
|
||||
raise self.error(f"Table '{table_name}' not found in {full_file_path}")
|
||||
|
||||
# Extract the matched table content
|
||||
table_content = matching_tables[0].group(2)
|
||||
|
||||
# Insert the table content into the current document
|
||||
self.state_machine.insert_input(table_content.splitlines(), full_file_path)
|
||||
return []
|
||||
|
||||
def setup(app):
|
||||
app.add_directive('include-table', TableInclude)
|
||||
@@ -0,0 +1,211 @@
|
||||
.. meta::
|
||||
:description: This page lists frequently asked questions about HIP
|
||||
:keywords: AMD, ROCm, HIP, FAQ, frequently asked questions
|
||||
|
||||
*******************************************************************************
|
||||
Frequently asked questions
|
||||
*******************************************************************************
|
||||
|
||||
This topic provides answers to frequently asked questions from new HIP users and
|
||||
users familiar with NVIDIA CUDA.
|
||||
|
||||
HIP Support
|
||||
===========
|
||||
|
||||
What hardware does HIP support?
|
||||
-------------------------------
|
||||
|
||||
HIP supports AMD and NVIDIA GPUs. See
|
||||
:ref:`prerequisites of the install guide<install_prerequisites>` for detailed
|
||||
information.
|
||||
|
||||
What operating systems does HIP support?
|
||||
----------------------------------------
|
||||
|
||||
Linux as well as Windows are supported by ROCm. The exact versions are listed in
|
||||
the system requirements for :ref:`rocm-install-on-linux:supported_distributions`
|
||||
and :ref:`rocm-install-on-windows:supported-skus-win`.
|
||||
|
||||
.. note::
|
||||
Not all HIP runtime API functions are yet supported on Windows.
|
||||
A note is added to those functions' documentation in the
|
||||
:ref:`HIP runtime API reference<runtime_api_reference>`.
|
||||
|
||||
What libraries does HIP provide?
|
||||
--------------------------------
|
||||
|
||||
HIP provides key math and AI libraries. See :doc:`rocm:reference/api-libraries`
|
||||
for the full list.
|
||||
|
||||
What NVIDIA CUDA features does HIP support?
|
||||
-------------------------------------------
|
||||
|
||||
The :doc:`NVIDIA CUDA runtime API supported by HIP<hipify:tables/CUDA_Runtime_API_functions_supported_by_HIP>`
|
||||
and :doc:`NVIDIA CUDA driver API supported by HIP<hipify:tables/CUDA_Driver_API_functions_supported_by_HIP>`
|
||||
pages describe which NVIDIA CUDA APIs are supported and what the equivalents are.
|
||||
The :doc:`HIP API documentation <doxygen/html/index>` describes each API and
|
||||
its limitations, if any, compared with the equivalent CUDA API.
|
||||
|
||||
The kernel language features are documented in the
|
||||
:doc:`/how-to/hip_cpp_language_extensions` page.
|
||||
|
||||
Relation to other GPGPU frameworks
|
||||
==================================
|
||||
|
||||
Is HIP a drop-in replacement for CUDA?
|
||||
--------------------------------------
|
||||
|
||||
The `HIPIFY <https://github.com/ROCm/HIPIFY>`_ tools can automatically convert
|
||||
almost all CUDA runtime code to HIP. Most device code needs no additional
|
||||
conversion because HIP and CUDA have the same signatures for math and built-in
|
||||
functions except for the name. HIP code provides similar performance as native
|
||||
CUDA code on NVIDIA platforms, plus the benefits of being compilable for AMD
|
||||
platforms.
|
||||
|
||||
Additional porting might be required to deal with architecture feature
|
||||
queries or CUDA capabilities that HIP doesn't support.
|
||||
|
||||
To better understand the syntax differences, see :doc:`CUDA to HIP API Function Comparison <reference/api_syntax>`
|
||||
or the :doc:`HIP porting guide <how-to/hip_porting_guide>`.
|
||||
|
||||
Can I install CUDA and ROCm on the same machine?
|
||||
------------------------------------------------
|
||||
|
||||
Yes, but you require a compatible GPU to run the compiled code.
|
||||
|
||||
On NVIDIA platforms, can I mix HIP code with CUDA code?
|
||||
-------------------------------------------------------
|
||||
|
||||
Yes. Most HIP types and data structures are ``typedef`` s to CUDA equivalents and
|
||||
can be used interchangeably. This can be useful for iteratively porting CUDA code.
|
||||
|
||||
See :doc:`how-to/hip_porting_guide` for more details.
|
||||
|
||||
Can a HIP binary run on both AMD and NVIDIA platforms?
|
||||
------------------------------------------------------
|
||||
|
||||
HIP is a source-portable language that can be compiled to run on AMD or NVIDIA
|
||||
platforms. However, the HIP tools don't create a "fat binary" that can run on
|
||||
both platforms.
|
||||
|
||||
Compiler related questions
|
||||
==========================
|
||||
|
||||
hipcc detected my platform incorrectly. What should I do?
|
||||
---------------------------------------------------------
|
||||
|
||||
The environment variable ``HIP_PLATFORM`` can be used to specify the platform
|
||||
for which the code is going to be compiled with ``hipcc``. See the
|
||||
:doc:`hipcc environment variables<hipcc:env>` for more information.
|
||||
|
||||
.. warning::
|
||||
|
||||
If you specify HIP_PLATFORM=NVIDIA with hipcc, you also need to pass ``-x cu``
|
||||
to hipcc when compiling files with the ``.hip`` file extension. Otherwise,
|
||||
nvcc will not recognize the ``.hip`` file extension and will fail with
|
||||
``nvcc fatal : Don't know what to do with <file>.hip``.
|
||||
|
||||
How to use HIP-Clang to build HIP programs?
|
||||
------------------------------------------------------
|
||||
|
||||
:doc:`hipcc <hipcc:index>` is a compiler driver. This means it is not a compiler
|
||||
but calls the appropriate compilers and sets some options.
|
||||
|
||||
The underlying compilers are :doc:`amdclang++ <llvm-project:index>` or
|
||||
`nvcc <https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html>`_,
|
||||
depending on the platform, and can be called directly.
|
||||
|
||||
What is HIP-Clang?
|
||||
------------------
|
||||
|
||||
HIP-Clang is a Clang/LLVM-based compiler used to compile HIP programs for AMD
|
||||
platforms. The executable is named :doc:`amdclang++ <llvm-project:index>` on
|
||||
Linux and ``clang++`` on Windows.
|
||||
|
||||
Can I link HIP device code with host code compiled with another compiler such as gcc, icc, or clang?
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
|
||||
Yes. HIP generates object code that conforms to the GCC ABI, and links with libstdc++.
|
||||
This means you can compile host code with the compiler of your choice and link the
|
||||
generated host object code with device code.
|
||||
|
||||
Can HIP applications be compiled with a C compiler?
|
||||
---------------------------------------------------
|
||||
|
||||
HIP is a C/C++ API that can be used with C compilers. However, this applies only
|
||||
to the API itself. Device code and the syntax for calling kernels must be
|
||||
compiled with a supported compiler like :doc:`hipcc <hipcc:index>`. The code
|
||||
objects that are generated with ``hipcc`` can, however, be used with a C
|
||||
compiler, as shown in the code examples below.
|
||||
|
||||
The following is the HIP device code, assumed to be saved in ``device.hip``:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
|
||||
__global__ void kernel(double* array, size_t size){
|
||||
const int x = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
if(x < size){array[x] = x;}
|
||||
};
|
||||
|
||||
extern "C"{
|
||||
hipError_t callKernel(int blocks, int threadsPerBlock, double* array, size_t size){
|
||||
kernel<<<blocks, threadsPerBlock, 0, hipStreamDefault>>>(array, size);
|
||||
return hipGetLastError();
|
||||
}
|
||||
}
|
||||
|
||||
The following is the host code, written in C, saved in ``host.c``:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#include <hip/hip_runtime_api.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define HIP_CHECK(c) { \
|
||||
if (c != hipSuccess){ \
|
||||
printf("HIP Error : %s", hipGetErrorString(c)); \
|
||||
printf(" %s %d\n", __FILE__, __LINE__); \
|
||||
exit(c); \
|
||||
} \
|
||||
}
|
||||
|
||||
// Forward declaration - the implementation needs to be compiled with
|
||||
// a device compiler like hipcc or amdclang++
|
||||
hipError_t callKernel(int blocks, int threadsPerBlock, double* array, size_t size);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
int blocks = 1024;
|
||||
int threadsPerBlock = 256;
|
||||
size_t arraySize = blocks * threadsPerBlock;
|
||||
double* d_array;
|
||||
double* h_array;
|
||||
h_array = (double*)malloc(arraySize * sizeof(double));
|
||||
|
||||
HIP_CHECK(hipMalloc((void**)&d_array, arraySize * sizeof(double)));
|
||||
HIP_CHECK(callKernel(blocks, threadsPerBlock, d_array, arraySize));
|
||||
HIP_CHECK(hipMemcpy(h_array, d_array, arraySize * sizeof(double), hipMemcpyDeviceToHost));
|
||||
HIP_CHECK(hipFree(d_array));
|
||||
|
||||
free(h_array);
|
||||
return 0;
|
||||
}
|
||||
|
||||
These files are then compiled and linked using
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
hipcc -c device.hip
|
||||
gcc host.c device.o $(hipconfig --cpp_config) -L/opt/rocm/lib -lamdhip64
|
||||
|
||||
assuming the default installation of ROCm in ``/opt/rocm``.
|
||||
|
||||
How to guard code specific to the host or the GPU?
|
||||
--------------------------------------------------
|
||||
|
||||
The compiler defines the ``__HIP_DEVICE_COMPILE__`` macro only when compiling
|
||||
device code.
|
||||
|
||||
Refer to the :doc:`how-to/hip_porting_guide` for more information.
|
||||
@@ -0,0 +1,102 @@
|
||||
#!/bin/bash
|
||||
# Copyright (C) 2019-2021 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
## generates documentation about clang options.
|
||||
|
||||
clang=/opt/rocm*/llvm/bin/clang
|
||||
|
||||
exec > clang_options.md
|
||||
|
||||
echo "# Support of Clang options"
|
||||
echo " Clang version: $($clang --version | head -1|sed 's:\(.*\) (.* \(.*\)).*:\1 \2:')"
|
||||
echo
|
||||
echo "|Option|Support|Description|"
|
||||
echo "|-------|------|-------|"
|
||||
|
||||
declare -A db
|
||||
while read a b; do
|
||||
if [[ "$a" != "" && "$b" != "" ]]; then
|
||||
db[$a]="$b"
|
||||
#echo "db[$a]=${db[$a]}"
|
||||
fi
|
||||
done <clang_options.txt
|
||||
#for K in "${!db[@]}"; do echo $K; done
|
||||
|
||||
tmpf=tmp_clang_option.txt
|
||||
|
||||
[[ -f $tmpf ]] && rm $tmpf
|
||||
|
||||
$clang --help | sed '1,5d'| while read a b; do
|
||||
if [[ "$a" != "-"* ]]; then
|
||||
desc="$a $b"
|
||||
elif [[ "$b" = *'>'* ]]; then
|
||||
opt=$(echo $a $b| sed -e 's:\(^-[^ ]*[= ]*<[^<>]*>\) *\(.*\):\1:')
|
||||
desc=$(echo $a $b| sed -e 's:\(^-[^ ]*[= ]*<[^<>]*>\) *\(.*\):\2:')
|
||||
if [[ "$opt" == "$desc" ]]; then
|
||||
opt="$a"
|
||||
desc="$b"
|
||||
fi
|
||||
else
|
||||
opt="$a"
|
||||
desc="$b"
|
||||
fi
|
||||
supp=
|
||||
key=$(printf "%s" "$opt" |sed 's:\([^ =<]*\).*:\1:')
|
||||
if [[ "$key" != "" ]]; then
|
||||
supp="${db[$key]}"
|
||||
#echo "opt=$opt supp=${db[$opt]}"
|
||||
fi
|
||||
if [[ "$supp" == "" ]]; then
|
||||
if [[ "$desc" = *AArch* ||\
|
||||
"$desc" = *MIPS* || \
|
||||
"$desc" = *ARM* || \
|
||||
"$desc" = *Arm* || \
|
||||
"$desc" = *SYCL* || \
|
||||
"$desc" = *PPC* || \
|
||||
"$desc" = *RISC-V* || \
|
||||
"$desc" = *WebAssembly* || \
|
||||
"$desc" = *Objective-C* || \
|
||||
"$opt" = *xray* \
|
||||
]]; then
|
||||
supp="n"
|
||||
elif [[ "$opt" = *sanity* ]]; then
|
||||
supp="h"
|
||||
else
|
||||
supp="s"
|
||||
fi
|
||||
fi
|
||||
s=$supp
|
||||
case $supp in
|
||||
s) supp="Supported";;
|
||||
n) supp="Unsupported";;
|
||||
h) supp="Supported on Host only";;
|
||||
esac
|
||||
|
||||
desc=$(echo "$desc"| sed -e 's:^ *::' -e 's:|:\\|:g')
|
||||
#echo a=$a
|
||||
#echo b=$b
|
||||
#echo opt=$opt
|
||||
#echo desc=$desc
|
||||
if [[ "$desc" != "" ]]; then
|
||||
printf "%s %s\n" "$key" "$s" >>$tmpf
|
||||
echo '|`'$opt'`|'$supp'|`'$desc'`|'
|
||||
fi
|
||||
done
|
||||
@@ -0,0 +1,300 @@
|
||||
.. meta::
|
||||
:description: How to debug using HIP.
|
||||
:keywords: AMD, ROCm, HIP, debugging, ltrace, ROCgdb, WinGDB
|
||||
|
||||
.. _debugging_with_hip:
|
||||
|
||||
*************************************************************************
|
||||
Debugging with HIP
|
||||
*************************************************************************
|
||||
|
||||
HIP debugging tools include `ltrace <https://ltrace.org/>`_ and :doc:`ROCgdb <rocgdb:index>`. External tools are available and can be found online. For example, if you're using Windows, you can use Microsoft Visual Studio and WinGDB.
|
||||
|
||||
You can trace and debug your code using the following tools and techniques.
|
||||
|
||||
Tracing
|
||||
================================================
|
||||
|
||||
You can use tracing to quickly observe the flow of an application before reviewing the detailed
|
||||
information provided by a command-line debugger. Tracing can be used to identify issues ranging
|
||||
from accidental API calls to calls made on a critical path.
|
||||
|
||||
ltrace is a standard Linux tool that provides a message to ``stderr`` on every dynamic library call. You
|
||||
can use ltrace to visualize the runtime behavior of the entire ROCm software stack.
|
||||
|
||||
Here's a simple command-line example that uses ltrace to trace HIP APIs and output:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ ltrace -C -e "hip*" ./hipGetChanDesc
|
||||
hipGetChanDesc->hipCreateChannelDesc(0x7ffdc4b66860, 32, 0, 0) = 0x7ffdc4b66860
|
||||
hipGetChanDesc->hipMallocArray(0x7ffdc4b66840, 0x7ffdc4b66860, 8, 8) = 0
|
||||
hipGetChanDesc->hipGetChannelDesc(0x7ffdc4b66848, 0xa63990, 5, 1) = 0
|
||||
hipGetChanDesc->hipFreeArray(0xa63990, 0, 0x7f8c7fe13778, 0x7ffdc4b66848) = 0
|
||||
PASSED!
|
||||
+++ exited (status 0) +++
|
||||
|
||||
|
||||
Here's another example that uses ltrace to trace hsa APIs and output:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ ltrace -C -e "hsa*" ./hipGetChanDesc
|
||||
libamdhip64.so.4->hsa_init(0, 0x7fff325a69d0, 0x9c80e0, 0 <unfinished ...>
|
||||
libhsa-runtime64.so.1->hsaKmtOpenKFD(0x7fff325a6590, 0x9c38c0, 0, 1) = 0
|
||||
libhsa-runtime64.so.1->hsaKmtGetVersion(0x7fff325a6608, 0, 0, 0) = 0
|
||||
libhsa-runtime64.so.1->hsaKmtReleaseSystemProperties(3, 0x80084b01, 0, 0) = 0
|
||||
libhsa-runtime64.so.1->hsaKmtAcquireSystemProperties(0x7fff325a6610, 0, 0, 1) = 0
|
||||
libhsa-runtime64.so.1->hsaKmtGetNodeProperties(0, 0x7fff325a66a0, 0, 0) = 0
|
||||
libhsa-runtime64.so.1->hsaKmtGetNodeMemoryProperties(0, 1, 0x9c42b0, 0x936012) = 0
|
||||
...
|
||||
<... hsaKmtCreateEvent resumed> ) = 0
|
||||
libhsa-runtime64.so.1->hsaKmtAllocMemory(0, 4096, 64, 0x7fff325a6690) = 0
|
||||
libhsa-runtime64.so.1->hsaKmtMapMemoryToGPUNodes(0x7f1202749000, 4096, 0x7fff325a6690, 0) = 0
|
||||
libhsa-runtime64.so.1->hsaKmtCreateEvent(0x7fff325a6700, 0, 0, 0x7fff325a66f0) = 0
|
||||
libhsa-runtime64.so.1->hsaKmtAllocMemory(1, 0x100000000, 576, 0x7fff325a67d8) = 0
|
||||
libhsa-runtime64.so.1->hsaKmtAllocMemory(0, 8192, 64, 0x7fff325a6790) = 0
|
||||
libhsa-runtime64.so.1->hsaKmtMapMemoryToGPUNodes(0x7f120273c000, 8192, 0x7fff325a6790, 0) = 0
|
||||
libhsa-runtime64.so.1->hsaKmtAllocMemory(0, 4096, 4160, 0x7fff325a6450) = 0
|
||||
libhsa-runtime64.so.1->hsaKmtMapMemoryToGPUNodes(0x7f120273a000, 4096, 0x7fff325a6450, 0) = 0
|
||||
libhsa-runtime64.so.1->hsaKmtSetTrapHandler(1, 0x7f120273a000, 4096, 0x7f120273c000) = 0
|
||||
<... hsa_init resumed> ) = 0
|
||||
libamdhip64.so.4->hsa_system_get_major_extension_table(513, 1, 24, 0x7f1202597930) = 0
|
||||
libamdhip64.so.4->hsa_iterate_agents(0x7f120171f050, 0, 0x7fff325a67f8, 0 <unfinished ...>
|
||||
libamdhip64.so.4->hsa_agent_get_info(0x94f110, 17, 0x7fff325a67e8, 0) = 0
|
||||
libamdhip64.so.4->hsa_amd_agent_iterate_memory_pools(0x94f110, 0x7f1201722816, 0x7fff325a67f0, 0x7f1201722816 <unfinished ...>
|
||||
libamdhip64.so.4->hsa_amd_memory_pool_get_info(0x9c7fb0, 0, 0x7fff325a6744, 0x7fff325a67f0) = 0
|
||||
libamdhip64.so.4->hsa_amd_memory_pool_get_info(0x9c7fb0, 1, 0x7fff325a6748, 0x7f1200d82df4) = 0
|
||||
...
|
||||
<... hsa_amd_agent_iterate_memory_pools resumed> ) = 0
|
||||
libamdhip64.so.4->hsa_agent_get_info(0x9dbf30, 17, 0x7fff325a67e8, 0) = 0
|
||||
<... hsa_iterate_agents resumed> ) = 0
|
||||
libamdhip64.so.4->hsa_agent_get_info(0x9dbf30, 0, 0x7fff325a6850, 3) = 0
|
||||
libamdhip64.so.4->hsa_agent_get_info(0x9dbf30, 0xa000, 0x9e7cd8, 0) = 0
|
||||
libamdhip64.so.4->hsa_agent_iterate_isas(0x9dbf30, 0x7f1201720411, 0x7fff325a6760, 0x7f1201720411) = 0
|
||||
libamdhip64.so.4->hsa_isa_get_info_alt(0x94e7c8, 0, 0x7fff325a6728, 1) = 0
|
||||
libamdhip64.so.4->hsa_isa_get_info_alt(0x94e7c8, 1, 0x9e7f90, 0) = 0
|
||||
libamdhip64.so.4->hsa_agent_get_info(0x9dbf30, 4, 0x9e7ce8, 0) = 0
|
||||
...
|
||||
<... hsa_amd_memory_pool_allocate resumed> ) = 0
|
||||
libamdhip64.so.4->hsa_ext_image_create(0x9dbf30, 0xa1c4c8, 0x7f10f2800000, 3 <unfinished ...>
|
||||
libhsa-runtime64.so.1->hsaKmtAllocMemory(0, 4096, 64, 0x7fff325a6740) = 0
|
||||
libhsa-runtime64.so.1->hsaKmtQueryPointerInfo(0x7f1202736000, 0x7fff325a65e0, 0, 0) = 0
|
||||
libhsa-runtime64.so.1->hsaKmtMapMemoryToGPUNodes(0x7f1202736000, 4096, 0x7fff325a66e8, 0) = 0
|
||||
<... hsa_ext_image_create resumed> ) = 0
|
||||
libamdhip64.so.4->hsa_ext_image_destroy(0x9dbf30, 0x7f1202736000, 0x9dbf30, 0 <unfinished ...>
|
||||
libhsa-runtime64.so.1->hsaKmtUnmapMemoryToGPU(0x7f1202736000, 0x7f1202736000, 4096, 0x9c8050) = 0
|
||||
libhsa-runtime64.so.1->hsaKmtFreeMemory(0x7f1202736000, 4096, 0, 0) = 0
|
||||
<... hsa_ext_image_destroy resumed> ) = 0
|
||||
libamdhip64.so.4->hsa_amd_memory_pool_free(0x7f10f2800000, 0x7f10f2800000, 256, 0x9e76f0) = 0
|
||||
PASSED!
|
||||
|
||||
Debugging
|
||||
================================================
|
||||
|
||||
You can use ROCgdb for debugging and profiling.
|
||||
|
||||
ROCgdb is the ROCm source-level debugger for Linux and is based on GNU Project debugger (GDB).
|
||||
the GNU source-level debugger, equivalent of CUDA-GDB, can be used with debugger frontends, such as Eclipse, Visual Studio Code, or GDB dashboard.
|
||||
For details, see (https://github.com/ROCm/ROCgdb).
|
||||
|
||||
Below is a sample how to use ROCgdb run and debug HIP application, ROCgdb is installed with ROCM package in the folder /opt/rocm/bin.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ export PATH=$PATH:/opt/rocm/bin
|
||||
$ rocgdb ./hipTexObjPitch
|
||||
GNU gdb (rocm-dkms-no-npi-hipclang-6549) 10.1
|
||||
Copyright (C) 2020 Free Software Foundation, Inc.
|
||||
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
|
||||
...
|
||||
For bug reporting instructions, please see:
|
||||
<https://github.com/ROCm/ROCgdb/issues>.
|
||||
Find the GDB manual and other documentation resources online at:
|
||||
<http://www.gnu.org/software/gdb/documentation/>.
|
||||
|
||||
...
|
||||
Reading symbols from ./hipTexObjPitch...
|
||||
(gdb) break main
|
||||
Breakpoint 1 at 0x4013d1: file /home/test/hip/tests/src/texture/hipTexObjPitch.cpp, line 98.
|
||||
(gdb) run
|
||||
Starting program: /home/test/hip/build/directed_tests/texture/hipTexObjPitch
|
||||
[Thread debugging using libthread_db enabled]
|
||||
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
|
||||
|
||||
Breakpoint 1, main ()
|
||||
at /home/test/hip/tests/src/texture/hipTexObjPitch.cpp:98
|
||||
98 texture2Dtest<float>();
|
||||
(gdb)c
|
||||
|
||||
Debugging HIP applications
|
||||
--------------------------------------------------------------------------------------------
|
||||
|
||||
The following Linux example shows how to get useful information from the debugger while running a
|
||||
simple memory copy test, which caused a segmentation fault issue.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
test: simpleTest2<?> numElements=4194304 sizeElements=4194304 bytes
|
||||
Segmentation fault (core dumped)
|
||||
|
||||
(gdb) run
|
||||
Starting program: /home/test/hipamd/build/directed_tests/runtimeApi/memory/hipMemcpy_simple
|
||||
[Thread debugging using libthread_db enabled]
|
||||
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
|
||||
|
||||
Breakpoint 1, main (argc=1, argv=0x7fffffffdea8)
|
||||
at /home/test/hip/tests/src/runtimeApi/memory/hipMemcpy_simple.cpp:147
|
||||
147 int main(int argc, char* argv[]) {
|
||||
(gdb) c
|
||||
Continuing.
|
||||
[New Thread 0x7ffff64c4700 (LWP 146066)]
|
||||
|
||||
Thread 1 "hipMemcpy_simpl" received signal SIGSEGV, Segmentation fault.
|
||||
0x000000000020f78e in simpleTest2<float> (numElements=4194304, usePinnedHost=true)
|
||||
at /home/test/hip/tests/src/runtimeApi/memory/hipMemcpy_simple.cpp:104
|
||||
104 A_h1[i] = 3.14f + 1000 * i;
|
||||
(gdb) bt
|
||||
#0 0x000000000020f78e in simpleTest2<float> (numElements=4194304, usePinnedHost=true)
|
||||
at /home/test/hip/tests/src/runtimeApi/memory/hipMemcpy_simple.cpp:104
|
||||
#1 0x000000000020e96c in main (argc=<optimized out>, argv=<optimized out>)
|
||||
at /home/test/hip/tests/src/runtimeApi/memory/hipMemcpy_simple.cpp:163
|
||||
(gdb) info thread
|
||||
Id Target Id Frame
|
||||
* 1 Thread 0x7ffff64c5880 (LWP 146060) "hipMemcpy_simpl" 0x000000000020f78e in simpleTest2<float> (numElements=4194304, usePinnedHost=true)
|
||||
at /home/test/hip/tests/src/runtimeApi/memory/hipMemcpy_simple.cpp:104
|
||||
2 Thread 0x7ffff64c4700 (LWP 146066) "hipMemcpy_simpl" 0x00007ffff6b0850b in ioctl
|
||||
() from /lib/x86_64-linux-gnu/libc.so.6
|
||||
(gdb) thread 2
|
||||
[Switching to thread 2 (Thread 0x7ffff64c4700 (LWP 146066))]
|
||||
#0 0x00007ffff6b0850b in ioctl () from /lib/x86_64-linux-gnu/libc.so.6
|
||||
(gdb) bt
|
||||
#0 0x00007ffff6b0850b in ioctl () from /lib/x86_64-linux-gnu/libc.so.6
|
||||
#1 0x00007ffff6604568 in ?? () from /opt/rocm/lib/libhsa-runtime64.so.1
|
||||
#2 0x00007ffff65fe73a in ?? () from /opt/rocm/lib/libhsa-runtime64.so.1
|
||||
#3 0x00007ffff659e4d6 in ?? () from /opt/rocm/lib/libhsa-runtime64.so.1
|
||||
#4 0x00007ffff65807de in ?? () from /opt/rocm/lib/libhsa-runtime64.so.1
|
||||
#5 0x00007ffff65932a2 in ?? () from /opt/rocm/lib/libhsa-runtime64.so.1
|
||||
#6 0x00007ffff654f547 in ?? () from /opt/rocm/lib/libhsa-runtime64.so.1
|
||||
#7 0x00007ffff7f76609 in start_thread () from /lib/x86_64-linux-gnu/libpthread.so.0
|
||||
#8 0x00007ffff6b13293 in clone () from /lib/x86_64-linux-gnu/libc.so.6
|
||||
(gdb) thread 1
|
||||
[Switching to thread 1 (Thread 0x7ffff64c5880 (LWP 146060))]
|
||||
#0 0x000000000020f78e in simpleTest2<float> (numElements=4194304, usePinnedHost=true)
|
||||
at /home/test/hip/tests/src/runtimeApi/memory/hipMemcpy_simple.cpp:104
|
||||
104 A_h1[i] = 3.14f + 1000 * i;
|
||||
(gdb) bt
|
||||
#0 0x000000000020f78e in simpleTest2<float> (numElements=4194304, usePinnedHost=true)
|
||||
at /home/test/hip/tests/src/runtimeApi/memory/hipMemcpy_simple.cpp:104
|
||||
#1 0x000000000020e96c in main (argc=<optimized out>, argv=<optimized out>)
|
||||
at /home/test/hip/tests/src/runtimeApi/memory/hipMemcpy_simple.cpp:163
|
||||
(gdb)
|
||||
...
|
||||
|
||||
Debugging HIP applications using Windows tools can be more informative than on Linux. Windows
|
||||
tools provides more visibility into debug codes, which makes it easier to inspect variables, watch
|
||||
multiple details, and examine call stacks.
|
||||
|
||||
Useful environment variables
|
||||
===================================================
|
||||
|
||||
HIP provides environment variables that allow HIP, hip-clang, or HSA drivers to prevent certain features
|
||||
and optimizations. These are not intended for production, but can be useful to diagnose
|
||||
synchronization problems in the application (or driver).
|
||||
|
||||
Some of the more widely used environment variables are described in this section. These are
|
||||
supported on the Linux ROCm path and Windows.
|
||||
|
||||
Kernel enqueue serialization
|
||||
---------------------------------------------------------------------------------
|
||||
|
||||
You can control kernel command serialization from the host:
|
||||
|
||||
``AMD_SERIALIZE_KERNEL``, for serializing kernel enqueue
|
||||
``AMD_SERIALIZE_KERNEL = 1``, Wait for completion before enqueue
|
||||
``AMD_SERIALIZE_KERNEL = 2``, Wait for completion after enqueue
|
||||
``AMD_SERIALIZE_KERNEL = 3``, Both
|
||||
|
||||
Or
|
||||
|
||||
``AMD_SERIALIZE_COPY``, for serializing copies
|
||||
``AMD_SERIALIZE_COPY = 1``, Wait for completion before enqueue
|
||||
``AMD_SERIALIZE_COPY = 2``, Wait for completion after enqueue
|
||||
``AMD_SERIALIZE_COPY = 3``, Both
|
||||
|
||||
So HIP runtime can wait for GPU idle before/after any GPU command depending on the environment
|
||||
setting.
|
||||
|
||||
Making device visible
|
||||
---------------------------------------------------------------------------------
|
||||
|
||||
For systems with multiple devices, you can choose to make only certain device(s) visible to HIP using
|
||||
``HIP_VISIBLE_DEVICES`` (or ``CUDA_VISIBLE_DEVICES`` on an NVIDIA platform). Once enabled, HIP can
|
||||
only view devices that have indices present in the sequence. For example:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ HIP_VISIBLE_DEVICES=0,1
|
||||
|
||||
Or in the application:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
if (totalDeviceNum > 2) {
|
||||
setenv("HIP_VISIBLE_DEVICES", "0,1,2", 1);
|
||||
assert(getDeviceNumber(false) == 3);
|
||||
... ...
|
||||
}
|
||||
|
||||
Dump code object
|
||||
---------------------------------------------------------------------------------
|
||||
|
||||
To analyze compiler-related issues, you can use the dump code object:
|
||||
``GPU_DUMP_CODE_OBJECT``.
|
||||
|
||||
HSA-related environment variables (Linux)
|
||||
-----------------------------------------------------------------------------------------------
|
||||
|
||||
HSA provides environment variables that help analyze issues in drivers or hardware.
|
||||
|
||||
* To isolate issues with hardware copy engines, you can use ``HSA_ENABLE_SDMA``.
|
||||
|
||||
``HSA_ENABLE_SDMA=0`` causes host-to-device and device-to-host copies to use compute shader
|
||||
blit kernels, rather than the dedicated DMA copy engines. Compute shader copies have low latency
|
||||
(typically < 5 us) and can achieve approximately 80% of the bandwidth of the DMA copy engine.
|
||||
|
||||
* To diagnose interrupt storm issues in the driver, you can use ``HSA_ENABLE_INTERRUPT``.
|
||||
|
||||
``HSA_ENABLE_INTERRUPT=0`` causes completion signals to be detected with memory-based
|
||||
polling, rather than interrupts.
|
||||
|
||||
HIP environment variable summary
|
||||
--------------------------------
|
||||
|
||||
Here are some of the more commonly used environment variables:
|
||||
|
||||
.. include-table:: data/env_variables_hip.rst
|
||||
:table: hip-env-debug
|
||||
|
||||
General debugging tips
|
||||
======================================================
|
||||
|
||||
* ``gdb --args`` can be used to pass the executable and arguments to ``gdb``.
|
||||
* You can set environment variables (``set env``) from within GDB on Linux:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
(gdb) set env AMD_SERIALIZE_KERNEL 3
|
||||
|
||||
.. note::
|
||||
This ``gdb`` command does not use an equal (=) sign.
|
||||
|
||||
* The GDB backtrace shows a path in the runtime. This is because a fault is caught by the runtime, but it is generated by an asynchronous command running on the GPU.
|
||||
* To determine the true location of a fault, you can force the kernels to run synchronously by setting the environment variables ``AMD_SERIALIZE_KERNEL=3`` and ``AMD_SERIALIZE_COPY=3``. This forces HIP runtime to wait for the kernel to finish running before returning. If the fault occurs when a kernel is running, you can see the code that launched the kernel inside the backtrace. The thread that's causing the issue is typically the one inside ``libhsa-runtime64.so``.
|
||||
* VM faults inside kernels can be caused by:
|
||||
|
||||
* Incorrect code (e.g., a for loop that extends past array boundaries)
|
||||
* Memory issues, such as invalid kernel arguments (null pointers, unregistered host pointers, bad pointers)
|
||||
* Synchronization issues
|
||||
* Compiler issues (incorrect code generation from the compiler)
|
||||
* Runtime issues
|
||||
@@ -0,0 +1,886 @@
|
||||
.. meta::
|
||||
:description: This chapter describes the built-in variables and functions that
|
||||
are accessible from HIP kernels and HIP's C++ support. It's
|
||||
intended for users who are familiar with CUDA kernel syntax and
|
||||
want to learn how HIP differs from CUDA.
|
||||
:keywords: AMD, ROCm, HIP, CUDA, c++ language extensions, HIP functions
|
||||
|
||||
################################################################################
|
||||
HIP C++ language extensions
|
||||
################################################################################
|
||||
|
||||
HIP extends the C++ language with additional features designed for programming
|
||||
heterogeneous applications. These extensions mostly relate to the kernel
|
||||
language, but some can also be applied to host functionality.
|
||||
|
||||
********************************************************************************
|
||||
HIP qualifiers
|
||||
********************************************************************************
|
||||
|
||||
Function-type qualifiers
|
||||
================================================================================
|
||||
|
||||
HIP introduces three different function qualifiers to mark functions for
|
||||
execution on the device or the host, and also adds new qualifiers to control
|
||||
inlining of functions.
|
||||
|
||||
.. _host_attr:
|
||||
|
||||
__host__
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
The ``__host__`` qualifier is used to specify functions for execution
|
||||
on the host. This qualifier is implicitly defined for any function where no
|
||||
``__host__``, ``__device__`` or ``__global__`` qualifier is added, in order to
|
||||
not break compatibility with existing C++ functions.
|
||||
|
||||
You can't combine ``__host__`` with ``__global__``.
|
||||
|
||||
__device__
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
The ``__device__`` qualifier is used to specify functions for execution on the
|
||||
device. They can only be called from other ``__device__`` functions or from
|
||||
``__global__`` functions.
|
||||
|
||||
You can combine it with the ``__host__`` qualifier and mark functions
|
||||
``__host__ __device__``. In this case, the function is compiled for the host and
|
||||
the device. Note that these functions can't use the HIP built-ins (e.g.,
|
||||
:ref:`threadIdx.x <thread_and_block_idx>` or :ref:`warpSize <warp_size>`), as
|
||||
they are not available on the host. If you need to use HIP grid coordinate
|
||||
functions, you can pass the necessary coordinate information as an argument.
|
||||
|
||||
__global__
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Functions marked ``__global__`` are executed on the device and are referred to
|
||||
as kernels. Their return type must be ``void``. Kernels have a special launch
|
||||
mechanism, and have to be launched from the host.
|
||||
|
||||
There are some restrictions on the parameters of kernels. Kernels can't:
|
||||
|
||||
* have a parameter of type ``std::initializer_list`` or ``va_list``
|
||||
* have a variable number of arguments
|
||||
* use references as parameters
|
||||
* use parameters having different sizes in host and device code, e.g. long double arguments, or structs containing long double members.
|
||||
* use struct-type arguments which have different layouts in host and device code.
|
||||
|
||||
Kernels can have variadic template parameters, but only one parameter pack,
|
||||
which must be the last item in the template parameter list.
|
||||
|
||||
.. note::
|
||||
Unlike CUDA, HIP does not support dynamic parallelism, meaning that kernels
|
||||
can not be called from the device.
|
||||
|
||||
Calling __global__ functions
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The launch mechanism for kernels differs from standard function calls, as they
|
||||
need an additional configuration, that specifies the grid and block dimensions
|
||||
(i.e. the amount of threads to be launched), as well as specifying the amount of
|
||||
shared memory per block and which stream to execute the kernel on.
|
||||
|
||||
Kernels are called using the triple chevron ``<<<>>>`` syntax known from CUDA,
|
||||
but HIP also supports the ``hipLaunchKernelGGL`` macro.
|
||||
|
||||
When using ``hipLaunchKernelGGL``, the first five configuration parameters must
|
||||
be:
|
||||
|
||||
* ``symbol kernelName``: The name of the kernel you want to launch. To support
|
||||
template kernels that contain several template parameters separated by use the
|
||||
``HIP_KERNEL_NAME`` macro to wrap the template instantiation
|
||||
(:doc:`HIPIFY <hipify:index>` inserts this automatically).
|
||||
* ``dim3 gridDim``: 3D-grid dimensions that specifies the number of blocks to
|
||||
launch.
|
||||
* ``dim3 blockDim``: 3D-block dimensions that specifies the number of threads in
|
||||
each block.
|
||||
* ``size_t dynamicShared``: The amount of additional shared dynamic memory to
|
||||
allocate per block.
|
||||
* ``hipStream_t``: The stream on which to run the kernel. A value of ``0``
|
||||
corresponds to the default stream.
|
||||
|
||||
The kernel arguments are listed after the configuration parameters.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <iostream>
|
||||
|
||||
#define HIP_CHECK(expression) \
|
||||
{ \
|
||||
const hipError_t err = expression; \
|
||||
if(err != hipSuccess){ \
|
||||
std::cerr << "HIP error: " << hipGetErrorString(err) \
|
||||
<< " at " << __LINE__ << "\n"; \
|
||||
} \
|
||||
}
|
||||
|
||||
// Performs a simple initialization of an array with the thread's index variables.
|
||||
// This function is only available in device code.
|
||||
__device__ void init_array(float * const a, const unsigned int arraySize){
|
||||
// globalIdx uniquely identifies a thread in a 1D launch configuration.
|
||||
const int globalIdx = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
// Each thread initializes a single element of the array.
|
||||
if(globalIdx < arraySize){
|
||||
a[globalIdx] = globalIdx;
|
||||
}
|
||||
}
|
||||
|
||||
// Rounds a value up to the next multiple.
|
||||
// This function is available in host and device code.
|
||||
__host__ __device__ constexpr int round_up_to_nearest_multiple(int number, int multiple){
|
||||
return (number + multiple - 1)/multiple;
|
||||
}
|
||||
|
||||
__global__ void example_kernel(float * const a, const unsigned int N)
|
||||
{
|
||||
// Initialize array.
|
||||
init_array(a, N);
|
||||
// Perform additional work:
|
||||
// - work with the array
|
||||
// - use the array in a different kernel
|
||||
// - ...
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
constexpr int N = 100000000; // problem size
|
||||
constexpr int blockSize = 256; //configurable block size
|
||||
|
||||
//needed number of blocks for the given problem size
|
||||
constexpr int gridSize = round_up_to_nearest_multiple(N, blockSize);
|
||||
|
||||
float *a;
|
||||
// allocate memory on the GPU
|
||||
HIP_CHECK(hipMalloc(&a, sizeof(*a) * N));
|
||||
|
||||
std::cout << "Launching kernel." << std::endl;
|
||||
example_kernel<<<dim3(gridSize), dim3(blockSize), 0/*example doesn't use shared memory*/, 0/*default stream*/>>>(a, N);
|
||||
// make sure kernel execution is finished by synchronizing. The CPU can also
|
||||
// execute other instructions during that time
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
std::cout << "Kernel execution finished." << std::endl;
|
||||
|
||||
HIP_CHECK(hipFree(a));
|
||||
}
|
||||
|
||||
Inline qualifiers
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
HIP adds the ``__noinline__`` and ``__forceinline__`` function qualifiers.
|
||||
|
||||
``__noinline__`` is a hint to the compiler to not inline the function, whereas
|
||||
``__forceinline__`` forces the compiler to inline the function. These qualifiers
|
||||
can be applied to both ``__host__`` and ``__device__`` functions.
|
||||
|
||||
``__noinline__`` and ``__forceinline__`` can not be used in combination.
|
||||
|
||||
__launch_bounds__
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
GPU multiprocessors have a fixed pool of resources (primarily registers and
|
||||
shared memory) which are shared by the actively running warps. Using more
|
||||
resources per thread can increase executed instructions per cycle but reduces
|
||||
the resources available for other warps and may therefore limit the occupancy,
|
||||
i.e. the number of warps that can be executed simultaneously. Thus GPUs have to
|
||||
balance resource usage between instruction- and thread-level parallelism.
|
||||
|
||||
``__launch_bounds__`` allows the application to provide hints that influence the
|
||||
resource (primarily registers) usage of the generated code. It is a function
|
||||
attribute that must be attached to a __global__ function:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
__global__ void __launch_bounds__(MAX_THREADS_PER_BLOCK, MIN_WARPS_PER_EXECUTION_UNIT)
|
||||
kernel_name(/*args*/);
|
||||
|
||||
The ``__launch_bounds__`` parameters are explained in the following sections:
|
||||
|
||||
MAX_THREADS_PER_BLOCK
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This parameter is a guarantee from the programmer, that kernel will not be
|
||||
launched with more threads than ``MAX_THREADS_PER_BLOCK``.
|
||||
|
||||
If no ``__launch_bounds__`` are specified, ``MAX_THREADS_PER_BLOCK`` is
|
||||
the maximum block size supported by the device (see
|
||||
:doc:`../reference/hardware_features`). Reducing ``MAX_THREADS_PER_BLOCK``
|
||||
allows the compiler to use more resources per thread than an unconstrained
|
||||
compilation. This might however reduce the amount of blocks that can run
|
||||
concurrently on a CU, thereby reducing occupancy and trading thread-level
|
||||
parallelism for instruction-level parallelism.
|
||||
|
||||
``MAX_THREADS_PER_BLOCK`` is particularly useful in cases, where the compiler is
|
||||
constrained by register usage in order to meet requirements of large block sizes
|
||||
that are never used at launch time.
|
||||
|
||||
The compiler can only use the hints to manage register usage, and does not
|
||||
automatically reduce shared memory usage. The compilation fails, if the compiler
|
||||
can not generate code that satisfies the launch bounds.
|
||||
|
||||
On NVCC this parameter maps to the ``.maxntid`` PTX directive.
|
||||
|
||||
When launching kernels HIP will validate the launch configuration to make sure
|
||||
the requested block size is not larger than ``MAX_THREADS_PER_BLOCK`` and
|
||||
return an error if it is exceeded.
|
||||
|
||||
If :doc:`AMD_LOG_LEVEL <./logging>` is set, detailed information will be shown
|
||||
in the error log message, including the launch configuration of the kernel and
|
||||
the specified ``__launch_bounds__``.
|
||||
|
||||
MIN_WARPS_PER_EXECUTION_UNIT
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This parameter specifies the minimum number of warps that must be able to run
|
||||
concurrently on an execution unit.
|
||||
``MIN_WARPS_PER_EXECUTION_UNIT`` is optional and defaults to 1 if not specified.
|
||||
Since active warps compete for the same fixed pool of resources, the compiler
|
||||
must constrain the resource usage of the warps. This option gives a lower
|
||||
bound to the occupancy of the kernel.
|
||||
|
||||
From this parameter, the compiler derives a maximum number of registers that can
|
||||
be used in the kernel. The amount of registers that can be used at most is
|
||||
:math:`\frac{\text{available registers}}{\text{MIN_WARPS_PER_EXECUTION_UNIT}}`,
|
||||
but it might also have other, architecture specific, restrictions.
|
||||
|
||||
The available registers per Compute Unit are listed in
|
||||
:doc:`rocm:reference/gpu-arch-specs`. Beware that these values are per Compute
|
||||
Unit, not per Execution Unit. On AMD GPUs a Compute Unit consists of 4 Execution
|
||||
Units, also known as SIMDs, each with their own register file. For more
|
||||
information see :doc:`../understand/hardware_implementation`.
|
||||
:cpp:struct:`hipDeviceProp_t` also has a field ``executionUnitsPerMultiprocessor``.
|
||||
|
||||
Memory space qualifiers
|
||||
================================================================================
|
||||
|
||||
HIP adds qualifiers to specify the memory space in which the variables are
|
||||
located.
|
||||
|
||||
Generally, variables allocated in host memory are not directly accessible within
|
||||
device code, while variables allocated in device memory are not directly
|
||||
accessible from the host code. More details on this can be found in
|
||||
:ref:`unified_memory`.
|
||||
|
||||
__device__
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Variables marked with ``__device__`` reside in device memory. It can be
|
||||
combined together with one of the following qualifiers, however these qualifiers
|
||||
also imply the ``__device__`` qualifier.
|
||||
|
||||
By default it can only be accessed from the threads on the device. In order to
|
||||
access it from the host, its address and size need to be queried using
|
||||
:cpp:func:`hipGetSymbolAddress` and :cpp:func:`hipGetSymbolSize` and copied with
|
||||
:cpp:func:`hipMemcpyToSymbol` or :cpp:func:`hipMemcpyFromSymbol`.
|
||||
|
||||
__constant__
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Variables marked with ``__constant__`` reside in device memory. Variables in
|
||||
that address space are routed through the constant cache, but that address space
|
||||
has a limited logical size.
|
||||
This memory space is read-only from within kernels and can only be set by the
|
||||
host before kernel execution.
|
||||
|
||||
To get the best performance benefit, these variables need a special access
|
||||
pattern to benefit from the constant cache - the access has to be uniform within
|
||||
a warp, otherwise the accesses are serialized.
|
||||
|
||||
The constant cache reduces the pressure on the other caches and may enable
|
||||
higher throughput and lower latency accesses.
|
||||
|
||||
To set the ``__constant__`` variables the host must copy the data to the device
|
||||
using :cpp:func:`hipMemcpyToSymbol`, for example:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
__constant__ int const_array[8];
|
||||
|
||||
void set_constant_memory(){
|
||||
int host_data[8] {1,2,3,4,5,6,7,8};
|
||||
|
||||
hipMemcpyToSymbol(const_array, host_data, sizeof(int) * 8);
|
||||
|
||||
// call kernel that accesses const_array
|
||||
}
|
||||
|
||||
__shared__
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Variables marked with ``__shared__`` are only accessible by threads within the
|
||||
same block and have the lifetime of that block. It is usually backed by on-chip
|
||||
shared memory, providing fast access to all threads within a block, which makes
|
||||
it perfectly suited for sharing variables.
|
||||
|
||||
Shared memory can be allocated statically within the kernel, but the size
|
||||
of it has to be known at compile time.
|
||||
|
||||
In order to dynamically allocate shared memory during runtime, but before the
|
||||
kernel is launched, the variable has to be declared ``extern``, and the kernel
|
||||
launch has to specify the needed amount of ``extern`` shared memory in the launch
|
||||
configuration. The statically allocated shared memory is allocated without this
|
||||
parameter.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
|
||||
extern __shared__ int shared_array[];
|
||||
|
||||
__global__ void kernel(){
|
||||
// initialize shared memory
|
||||
shared_array[threadIdx.x] = threadIdx.x;
|
||||
// use shared memory - synchronize to make sure, that all threads of the
|
||||
// block see all changes to shared memory
|
||||
__syncthreads();
|
||||
}
|
||||
|
||||
int main(){
|
||||
//shared memory in this case depends on the configurable block size
|
||||
constexpr int blockSize = 256;
|
||||
constexpr int sharedMemSize = blockSize * sizeof(int);
|
||||
constexpr int gridSize = 2;
|
||||
|
||||
kernel<<<dim3(gridSize), dim3(blockSize), sharedMemSize, 0>>>();
|
||||
}
|
||||
|
||||
__managed__
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Managed memory is a special qualifier, that makes the marked memory available on
|
||||
the device and on the host. For more details see :ref:`unified_memory`.
|
||||
|
||||
__restrict__
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
The ``__restrict__`` keyword tells the compiler that the associated memory
|
||||
pointer does not alias with any other pointer in the function. This can help the
|
||||
compiler perform better optimizations. For best results, every pointer passed to
|
||||
a function should use this keyword.
|
||||
|
||||
********************************************************************************
|
||||
Built-in constants
|
||||
********************************************************************************
|
||||
|
||||
HIP defines some special built-in constants for use in device code.
|
||||
|
||||
These built-ins are not implicitly defined by the compiler, the
|
||||
``hip_runtime.h`` header has to be included instead.
|
||||
|
||||
Index built-ins
|
||||
================================================================================
|
||||
|
||||
Kernel code can use these identifiers to distinguish between the different
|
||||
threads and blocks within a kernel.
|
||||
|
||||
These built-ins are of type dim3, and are constant for each thread, but differ
|
||||
between the threads or blocks, and are initialized at kernel launch.
|
||||
|
||||
blockDim and gridDim
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
``blockDim`` and ``gridDim`` contain the sizes specified at kernel launch.
|
||||
``blockDim`` contains the amount of threads in the x-, y- and z-dimensions of
|
||||
the block of threads. Similarly ``gridDim`` contains the amount of blocks in the
|
||||
grid.
|
||||
|
||||
.. _thread_and_block_idx:
|
||||
|
||||
threadIdx and blockIdx
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
``threadIdx`` and ``blockIdx`` can be used to identify the threads and blocks
|
||||
within the kernel.
|
||||
|
||||
``threadIdx`` identifies the thread within a block, meaning its values are
|
||||
within ``0`` and ``blockDim.{x,y,z} - 1``. Likewise ``blockIdx`` identifies the
|
||||
block within the grid, and the values are within ``0`` and ``gridDim.{} - 1``.
|
||||
|
||||
A global unique identifier of a three-dimensional grid can be calculated using
|
||||
the following code:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
(threadIdx.x + blockIdx.x * blockDim.x) +
|
||||
(threadIdx.y + blockIdx.y * blockDim.y) * blockDim.x +
|
||||
(threadIdx.z + blockIdx.z * blockDim.z) * blockDim.x * blockDim.y
|
||||
|
||||
.. _warp_size:
|
||||
|
||||
warpSize
|
||||
================================================================================
|
||||
|
||||
The ``warpSize`` constant contains the number of threads per warp for the given
|
||||
target device. It can differ between different architectures, and on RDNA
|
||||
architectures it can even differ between kernel launches, depending on whether
|
||||
they run in CU or WGP mode. See the
|
||||
:doc:`hardware features <../reference/hardware_features>` for more
|
||||
information.
|
||||
|
||||
Since ``warpSize`` can differ between devices, it can not be assumed to be a
|
||||
compile-time constant on the host. It has to be queried using
|
||||
:cpp:func:`hipDeviceGetAttribute` or :cpp:func:`hipDeviceGetProperties`, e.g.:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
int val;
|
||||
hipDeviceGetAttribute(&val, hipDeviceAttributeWarpSize, deviceId);
|
||||
|
||||
.. note::
|
||||
|
||||
``warpSize`` should not be assumed to be a specific value in portable HIP
|
||||
applications. NVIDIA devices return 32 for this variable; AMD devices return
|
||||
64 for gfx9 and 32 for gfx10 and above. HIP doesn't support ``warpSize`` of
|
||||
64 on gfx10 and above. While code that assumes a ``warpSize``
|
||||
of 32 can run on devices with a ``warpSize`` of 64, it only utilizes half of
|
||||
the compute resources.
|
||||
|
||||
********************************************************************************
|
||||
Vector types
|
||||
********************************************************************************
|
||||
|
||||
These types are not automatically provided by the compiler. The
|
||||
``hip_vector_types.h`` header, which is also included by ``hip_runtime.h`` has
|
||||
to be included to use these types.
|
||||
|
||||
Fundamental vector types
|
||||
================================================================================
|
||||
|
||||
Fundamental vector types derive from the `fundamental C++ integral and
|
||||
floating-point types <https://en.cppreference.com/w/cpp/language/types>`_. These
|
||||
types are defined in ``hip_vector_types.h``, which is included by
|
||||
``hip_runtime.h``.
|
||||
|
||||
All vector types can be created with ``1``, ``2``, ``3`` or ``4`` elements, the
|
||||
corresponding type is ``<fundamental_type>i``, where ``i`` is the number of
|
||||
elements.
|
||||
|
||||
All vector types support a constructor function of the form
|
||||
``make_<type_name>()``. For example,
|
||||
``float3 make_float3(float x, float y, float z)`` creates a vector of type
|
||||
``float3`` with value ``(x,y,z)``.
|
||||
The elements of the vectors can be accessed using their members ``x``, ``y``,
|
||||
``z``, and ``w``.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
double2 d2_vec = make_double2(2.0, 4.0);
|
||||
double first_elem = d2_vec.x;
|
||||
|
||||
HIP supports vectors created from the following fundamental types:
|
||||
|
||||
.. list-table::
|
||||
:widths: 50 50
|
||||
|
||||
*
|
||||
- **Integral Types**
|
||||
-
|
||||
*
|
||||
- ``char``
|
||||
- ``uchar``
|
||||
*
|
||||
- ``short``
|
||||
- ``ushort``
|
||||
*
|
||||
- ``int``
|
||||
- ``uint``
|
||||
*
|
||||
- ``long``
|
||||
- ``ulong``
|
||||
*
|
||||
- ``longlong``
|
||||
- ``ulonglong``
|
||||
*
|
||||
- **Floating-Point Types**
|
||||
-
|
||||
*
|
||||
- ``float``
|
||||
-
|
||||
*
|
||||
- ``double``
|
||||
-
|
||||
|
||||
.. _dim3:
|
||||
|
||||
dim3
|
||||
================================================================================
|
||||
|
||||
``dim3`` is a special three-dimensional unsigned integer vector type that is
|
||||
commonly used to specify grid and group dimensions for kernel launch
|
||||
configurations.
|
||||
|
||||
Its constructor accepts up to three arguments. The unspecified dimensions are
|
||||
initialized to 1.
|
||||
|
||||
********************************************************************************
|
||||
Built-in device functions
|
||||
********************************************************************************
|
||||
|
||||
.. _memory_fence_instructions:
|
||||
|
||||
Memory fence instructions
|
||||
================================================================================
|
||||
|
||||
HIP does not enforce strict ordering on memory operations, meaning, that the
|
||||
order in which memory accesses are executed, is not necessarily the order in
|
||||
which other threads observe these changes. So it can not be assumed, that data
|
||||
written by one thread is visible by another thread without synchronization.
|
||||
|
||||
Memory fences are a way to enforce a sequentially consistent order on the memory
|
||||
operations. This means, that all writes to memory made before a memory fence are
|
||||
observed by all threads after the fence. The scope of these fences depends on
|
||||
what specific memory fence is called.
|
||||
|
||||
HIP supports ``__threadfence()``, ``__threadfence_block()`` and
|
||||
``__threadfence_system()``:
|
||||
|
||||
* ``__threadfence_block()`` orders memory accesses for all threads within a thread block.
|
||||
* ``__threadfence()`` orders memory accesses for all threads on a device.
|
||||
* ``__threadfence_system()`` orders memory accesses for all threads in the system, making writes to memory visible to other devices and the host
|
||||
|
||||
.. _synchronization_functions:
|
||||
|
||||
Synchronization functions
|
||||
================================================================================
|
||||
|
||||
Synchronization functions cause all threads in a group to wait at this
|
||||
synchronization point until all threads reached it. These functions implicitly
|
||||
include a :ref:`threadfence <memory_fence_instructions>`, thereby ensuring
|
||||
visibility of memory accesses for the threads in the group.
|
||||
|
||||
The ``__syncthreads()`` function comes in different versions.
|
||||
|
||||
``void __syncthreads()`` simply synchronizes the threads of a block. The other
|
||||
versions additionally evaluate a predicate:
|
||||
|
||||
``int __syncthreads_count(int predicate)`` returns the number of threads for
|
||||
which the predicate evaluates to non-zero.
|
||||
|
||||
``int __syncthreads_and(int predicate)`` returns non-zero if the predicate
|
||||
evaluates to non-zero for all threads.
|
||||
|
||||
``int __syncthreads_or(int predicate)`` returns non-zero if any of the
|
||||
predicates evaluates to non-zero.
|
||||
|
||||
The Cooperative Groups API offers options to synchronize threads on a developer
|
||||
defined set of thread groups. For further information, check the
|
||||
:ref:`Cooperative Groups API reference <cooperative_groups_reference>` or the
|
||||
:ref:`Cooperative Groups section in the programming guide
|
||||
<cooperative_groups_how-to>`.
|
||||
|
||||
Math functions
|
||||
================================================================================
|
||||
|
||||
HIP-Clang supports a set of math operations that are callable from the device.
|
||||
HIP supports most of the device functions supported by CUDA. These are described
|
||||
on :ref:`Math API page <math_api_reference>`.
|
||||
|
||||
Texture functions
|
||||
================================================================================
|
||||
|
||||
The supported texture functions are listed in ``texture_fetch_functions.h`` and
|
||||
``texture_indirect_functions.h`` header files in the
|
||||
`HIP-AMD backend repository <https://github.com/ROCm/clr/blob/develop/hipamd/include/hip/amd_detail>`_.
|
||||
|
||||
Texture functions are not supported on some devices. To determine if texture functions are supported
|
||||
on your device, use ``Macro __HIP_NO_IMAGE_SUPPORT == 1``. You can query the attribute
|
||||
``hipDeviceAttributeImageSupport`` to check if texture functions are supported in the host runtime
|
||||
code.
|
||||
|
||||
Surface functions
|
||||
================================================================================
|
||||
|
||||
The supported surface functions are located on :ref:`Surface object reference
|
||||
page <surface_object_reference>`.
|
||||
|
||||
Timer functions
|
||||
================================================================================
|
||||
|
||||
HIP provides device functions to read a high-resolution timer from within the
|
||||
kernel.
|
||||
|
||||
The following functions count the cycles on the device, where the rate varies
|
||||
with the actual frequency.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
clock_t clock()
|
||||
long long int clock64()
|
||||
|
||||
.. note::
|
||||
|
||||
``clock()`` and ``clock64()`` do not work properly on AMD RDNA3 (GFX11) graphic processors.
|
||||
|
||||
The difference between the returned values represents the cycles used.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
__global void kernel(){
|
||||
long long int start = clock64();
|
||||
// kernel code
|
||||
long long int stop = clock64();
|
||||
long long int cycles = stop - start;
|
||||
}
|
||||
|
||||
``long long int wall_clock64()`` returns the wall clock time on the device, with a constant, fixed frequency.
|
||||
The frequency is device dependent and can be queried using:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
int wallClkRate = 0; //in kilohertz
|
||||
hipDeviceGetAttribute(&wallClkRate, hipDeviceAttributeWallClockRate, deviceId);
|
||||
|
||||
.. _atomic functions:
|
||||
|
||||
Atomic functions
|
||||
================================================================================
|
||||
|
||||
Atomic functions are read-modify-write (RMW) operations, whose result is visible
|
||||
to all other threads on the scope of the atomic operation, once the operation
|
||||
completes.
|
||||
|
||||
If multiple instructions from different devices or threads target the same
|
||||
memory location, the instructions are serialized in an undefined order.
|
||||
|
||||
Atomic operations in kernels can operate on block scope (i.e. shared memory),
|
||||
device scope (global memory), or system scope (system memory), depending on
|
||||
:doc:`hardware support <../reference/hardware_features>`.
|
||||
|
||||
The listed functions are also available with the ``_system`` (e.g.
|
||||
``atomicAdd_system``) suffix, operating on system scope, which includes host
|
||||
memory and other GPUs' memory. The functions without suffix operate on shared
|
||||
or global memory on the executing device, depending on the memory space of the
|
||||
variable.
|
||||
|
||||
HIP supports the following atomic operations, where ``TYPE`` is one of ``int``,
|
||||
``unsigned int``, ``unsigned long``, ``unsigned long long``, ``float`` or
|
||||
``double``, while ``INTEGER`` is ``int``, ``unsigned int``, ``unsigned long``,
|
||||
``unsigned long long``:
|
||||
|
||||
.. list-table:: Atomic operations
|
||||
|
||||
* - ``TYPE atomicAdd(TYPE* address, TYPE val)``
|
||||
|
||||
* - ``TYPE atomicSub(TYPE* address, TYPE val)``
|
||||
|
||||
* - ``TYPE atomicMin(TYPE* address, TYPE val)``
|
||||
* - ``long long atomicMin(long long* address, long long val)``
|
||||
|
||||
* - ``TYPE atomicMax(TYPE* address, TYPE val)``
|
||||
* - ``long long atomicMax(long long* address, long long val)``
|
||||
|
||||
* - ``TYPE atomicExch(TYPE* address, TYPE val)``
|
||||
|
||||
* - ``TYPE atomicCAS(TYPE* address, TYPE compare, TYPE val)``
|
||||
|
||||
* - ``INTEGER atomicAnd(INTEGER* address, INTEGER val)``
|
||||
|
||||
* - ``INTEGER atomicOr(INTEGER* address, INTEGER val)``
|
||||
|
||||
* - ``INTEGER atomicXor(INTEGER* address, INTEGER val)``
|
||||
|
||||
* - ``unsigned int atomicInc(unsigned int* address)``
|
||||
|
||||
* - ``unsigned int atomicDec(unsigned int* address)``
|
||||
|
||||
Unsafe floating-point atomic operations
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Some HIP devices support fast atomic operations on floating-point values. For
|
||||
example, ``atomicAdd`` on single- or double-precision floating-point values may
|
||||
generate a hardware instruction that is faster than emulating the atomic
|
||||
operation using an atomic compare-and-swap (CAS) loop.
|
||||
|
||||
On some devices, fast atomic instructions can produce results that differ from
|
||||
the version implemented with atomic CAS loops. For example, some devices
|
||||
will use different rounding or denormal modes, and some devices produce
|
||||
incorrect answers if fast floating-point atomic instructions target fine-grained
|
||||
memory allocations.
|
||||
|
||||
The HIP-Clang compiler offers compile-time options to control the generation of
|
||||
unsafe atomic instructions. By default the compiler does not generate unsafe
|
||||
instructions. This is the same behaviour as with the ``-mno-unsafe-fp-atomics``
|
||||
compilation flag. The ``-munsafe-fp-atomics`` flag indicates to the compiler
|
||||
that all floating-point atomic function calls are allowed to use an unsafe
|
||||
version, if one exists. For example, on some devices, this flag indicates to the
|
||||
compiler that no floating-point ``atomicAdd`` function can target fine-grained
|
||||
memory. These options are applied globally for the entire compilation.
|
||||
|
||||
HIP provides special functions that override the global compiler option for safe
|
||||
or unsafe atomic functions.
|
||||
|
||||
The ``safe`` prefix always generates safe atomic operations, even when
|
||||
``-munsafe-fp-atomics`` is used, whereas ``unsafe`` always generates fast atomic
|
||||
instructions, even when ``-mno-unsafe-fp-atomics``. The following table lists
|
||||
the safe and unsafe atomic functions, where ``FLOAT_TYPE`` is either ``float``
|
||||
or ``double``.
|
||||
|
||||
.. list-table:: AMD specific atomic operations
|
||||
|
||||
* - ``FLOAT_TYPE unsafeAtomicAdd(FLOAT_TYPE* address, FLOAT_TYPE val)``
|
||||
|
||||
* - ``FLOAT_TYPE safeAtomicAdd(FLOAT_TYPE* address, FLOAT_TYPE val)``
|
||||
|
||||
.. _warp-cross-lane:
|
||||
|
||||
Warp cross-lane functions
|
||||
================================================================================
|
||||
|
||||
Threads in a warp are referred to as ``lanes`` and are numbered from ``0`` to
|
||||
``warpSize - 1``. Warp cross-lane functions cooperate across all lanes in a
|
||||
warp. AMD GPUs guarantee, that all warp lanes are executed in lockstep, whereas
|
||||
NVIDIA GPUs that support Independent Thread Scheduling might require additional
|
||||
synchronization, or the use of the ``__sync`` variants.
|
||||
|
||||
Note that different devices can have different warp sizes. You should query the
|
||||
:ref:`warpSize <warp_size>` in portable code and not assume a fixed warp size.
|
||||
|
||||
All mask values returned or accepted by these built-ins are 64-bit unsigned
|
||||
integer values, even when compiled for a device with 32 threads per warp. On
|
||||
such devices the higher bits are unused. CUDA code ported to HIP requires
|
||||
changes to ensure that the correct type is used.
|
||||
|
||||
Note that the ``__sync`` variants are made available in ROCm 6.2, but disabled by
|
||||
default to help with the transition to 64-bit masks. They can be enabled by
|
||||
setting the preprocessor macro ``HIP_ENABLE_WARP_SYNC_BUILTINS``. These built-ins
|
||||
will be enabled unconditionally in the next ROCm release. Wherever possible, the
|
||||
implementation includes a static assert to check that the program source uses
|
||||
the correct type for the mask.
|
||||
|
||||
The ``_sync`` variants require a 64-bit unsigned integer mask argument that
|
||||
specifies the lanes of the warp that will participate. Each participating thread
|
||||
must have its own bit set in its mask argument, and all active threads specified
|
||||
in any mask argument must execute the same call with the same mask, otherwise
|
||||
the result is undefined.
|
||||
|
||||
.. _warp_vote_functions:
|
||||
|
||||
Warp vote and ballot functions
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
int __all(int predicate)
|
||||
int __any(int predicate)
|
||||
unsigned long long __ballot(int predicate)
|
||||
unsigned long long __activemask()
|
||||
|
||||
int __all_sync(unsigned long long mask, int predicate)
|
||||
int __any_sync(unsigned long long mask, int predicate)
|
||||
unsigned long long __ballot_sync(unsigned long long mask, int predicate)
|
||||
|
||||
You can use ``__any`` and ``__all`` to get a summary view of the predicates evaluated by the
|
||||
participating lanes.
|
||||
|
||||
* ``__any()``: Returns 1 if the predicate is non-zero for any participating lane, otherwise it returns 0.
|
||||
|
||||
* ``__all()``: Returns 1 if the predicate is non-zero for all participating lanes, otherwise it returns 0.
|
||||
|
||||
To determine if the target platform supports the any/all instruction, you can
|
||||
query the ``hasWarpVote`` device property on the host or use the
|
||||
``HIP_ARCH_HAS_WARP_VOTE`` compiler definition in device code.
|
||||
|
||||
``__ballot`` returns a bit mask containing the 1-bit predicate value from each
|
||||
lane. The nth bit of the result contains the bit contributed by the nth lane.
|
||||
|
||||
``__activemask()`` returns a bit mask of currently active warp lanes. The nth
|
||||
bit of the result is 1 if the nth lane is active.
|
||||
|
||||
Note that the ``__ballot`` and ``__activemask`` built-ins in HIP have a 64-bit return
|
||||
value (unlike the 32-bit value returned by the CUDA built-ins). Code ported from
|
||||
CUDA should be adapted to support the larger warp sizes that the HIP version
|
||||
requires.
|
||||
|
||||
Applications can test whether the target platform supports the ``__ballot`` or
|
||||
``__activemask`` instructions using the ``hasWarpBallot`` device property in host
|
||||
code or the ``HIP_ARCH_HAS_WARP_BALLOT`` macro defined by the compiler for device
|
||||
code.
|
||||
|
||||
Warp match functions
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
unsigned long long __match_any(T value)
|
||||
unsigned long long __match_all(T value, int *pred)
|
||||
|
||||
unsigned long long __match_any_sync(unsigned long long mask, T value)
|
||||
unsigned long long __match_all_sync(unsigned long long mask, T value, int *pred)
|
||||
|
||||
``T`` can be a 32-bit integer type, 64-bit integer type or a single precision or
|
||||
double precision floating point type.
|
||||
|
||||
``__match_any`` returns a bit mask where the n-th bit is set to 1 if the n-th
|
||||
lane has the same ``value`` as the current lane, and 0 otherwise.
|
||||
|
||||
``__match_all`` returns a bit mask with the bits of the participating lanes are
|
||||
set to 1 if all lanes have the same ``value``, and 0 otherwise.
|
||||
The predicate ``pred`` is set to true if all participating threads have the same
|
||||
``value``, and false otherwise.
|
||||
|
||||
Warp shuffle functions
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
T __shfl (T var, int srcLane, int width=warpSize);
|
||||
T __shfl_up (T var, unsigned int delta, int width=warpSize);
|
||||
T __shfl_down (T var, unsigned int delta, int width=warpSize);
|
||||
T __shfl_xor (T var, int laneMask, int width=warpSize);
|
||||
|
||||
T __shfl_sync (unsigned long long mask, T var, int srcLane, int width=warpSize);
|
||||
T __shfl_up_sync (unsigned long long mask, T var, unsigned int delta, int width=warpSize);
|
||||
T __shfl_down_sync (unsigned long long mask, T var, unsigned int delta, int width=warpSize);
|
||||
T __shfl_xor_sync (unsigned long long mask, T var, int laneMask, int width=warpSize);
|
||||
|
||||
``T`` can be a 32-bit integer type, 64-bit integer type or a single precision or
|
||||
double precision floating point type.
|
||||
|
||||
The warp shuffle functions exchange values between threads within a warp.
|
||||
|
||||
The optional ``width`` argument specifies subgroups, in which the warp can be
|
||||
divided to share the variables.
|
||||
It has to be a power of two smaller than or equal to ``warpSize``. If it is
|
||||
smaller than ``warpSize``, the warp is grouped into separate groups, that are each
|
||||
indexed from 0 to width as if it was its own entity, and only the lanes within
|
||||
that subgroup participate in the shuffle. The lane indices in the subgroup are
|
||||
given by ``laneIdx % width``.
|
||||
|
||||
The different shuffle functions behave as following:
|
||||
|
||||
``__shfl``
|
||||
The thread reads the value from the lane specified in ``srcLane``.
|
||||
|
||||
``__shfl_up``
|
||||
The thread reads ``var`` from lane ``laneIdx - delta``, thereby "shuffling"
|
||||
the values of the lanes of the warp "up". If the resulting source lane is out
|
||||
of range, the thread returns its own ``var``.
|
||||
|
||||
``__shfl_down``
|
||||
The thread reads ``var`` from lane ``laneIdx - delta``, thereby "shuffling"
|
||||
the values of the lanes of the warp "down". If the resulting source lane is
|
||||
out of range, the thread returns its own ``var``.
|
||||
|
||||
``__shfl_xor``
|
||||
The thread reads ``var`` from lane ``laneIdx xor lane_mask``. If ``width`` is
|
||||
smaller than ``warpSize``, the threads can read values from subgroups before
|
||||
the current subgroup. If it tries to read values from later subgroups, the
|
||||
function returns the ``var`` of the calling thread.
|
||||
|
||||
Warp matrix functions
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Warp matrix functions allow a warp to cooperatively operate on small matrices
|
||||
that have elements spread over lanes in an unspecified manner.
|
||||
|
||||
HIP does not support warp matrix types or functions.
|
||||
|
||||
Cooperative groups functions
|
||||
================================================================================
|
||||
|
||||
You can use cooperative groups to synchronize groups of threads across thread
|
||||
blocks. It also provide a way of communicating between these groups.
|
||||
|
||||
For further information, check the :ref:`Cooperative Groups API reference
|
||||
<cooperative_groups_reference>` or the :ref:`Cooperative Groups programming
|
||||
guide <cooperative_groups_how-to>`.
|
||||
@@ -0,0 +1,649 @@
|
||||
.. meta::
|
||||
:description: This chapter presents how to port the CUDA driver API and showcases equivalent operations in HIP.
|
||||
:keywords: AMD, ROCm, HIP, CUDA, driver API, porting, port
|
||||
|
||||
.. _porting_driver_api:
|
||||
|
||||
*******************************************************************************
|
||||
Porting CUDA driver API
|
||||
*******************************************************************************
|
||||
|
||||
CUDA provides separate driver and runtime APIs. The two APIs generally provide
|
||||
the similar functionality and mostly can be used interchangeably, however the
|
||||
driver API allows for more fine-grained control over the kernel level
|
||||
initialization, contexts and module management. This is all taken care of
|
||||
implicitly by the runtime API.
|
||||
|
||||
* Driver API calls begin with the prefix ``cu``, while runtime API calls begin
|
||||
with the prefix ``cuda``. For example, the driver API contains
|
||||
``cuEventCreate``, while the runtime API contains ``cudaEventCreate``, which
|
||||
has similar functionality.
|
||||
|
||||
* The driver API offers two additional low-level functionalities not exposed by
|
||||
the runtime API: module management ``cuModule*`` and context management
|
||||
``cuCtx*`` APIs.
|
||||
|
||||
HIP does not explicitly provide two different APIs, the corresponding functions
|
||||
for the CUDA driver API are available in the HIP runtime API, and are usually
|
||||
prefixed with ``hipDrv``. The module and context functionality is available with
|
||||
the ``hipModule`` and ``hipCtx`` prefix.
|
||||
|
||||
cuModule API
|
||||
================================================================================
|
||||
|
||||
The Module section of the driver API provides additional control over how and
|
||||
when accelerator code objects are loaded. For example, the driver API enables
|
||||
code objects to load from files or memory pointers. Symbols for kernels or
|
||||
global data are extracted from the loaded code objects. In contrast, the runtime
|
||||
API loads automatically and, if necessary, compiles all the kernels from an
|
||||
executable binary when it runs. In this mode, kernel code must be compiled using
|
||||
NVCC so that automatic loading can function correctly.
|
||||
|
||||
The Module features are useful in an environment that generates the code objects
|
||||
directly, such as a new accelerator language front end. NVCC is not used here.
|
||||
Instead, the environment might have a different kernel language or compilation
|
||||
flow. Other environments have many kernels and don't want all of them to be
|
||||
loaded automatically. The Module functions load the generated code objects and
|
||||
launch kernels. Similar to the cuModule API, HIP defines a hipModule API that
|
||||
provides similar explicit control over code object management.
|
||||
|
||||
.. _context_driver_api:
|
||||
|
||||
cuCtx API
|
||||
================================================================================
|
||||
|
||||
The driver API defines "Context" and "Devices" as separate entities.
|
||||
Contexts contain a single device, and a device can theoretically have multiple contexts.
|
||||
Each context contains a set of streams and events specific to the context.
|
||||
Historically, contexts also defined a unique address space for the GPU. This might no longer be the case in unified memory platforms, because the CPU and all the devices in the same process share a single unified address space.
|
||||
The Context APIs also provide a mechanism to switch between devices, which enables a single CPU thread to send commands to different GPUs.
|
||||
HIP and recent versions of the CUDA Runtime provide other mechanisms to accomplish this feat, for example, using streams or ``cudaSetDevice``.
|
||||
|
||||
The CUDA runtime API unifies the Context API with the Device API. This simplifies the APIs and has little loss of functionality. This is because each context can contain a single device, and the benefits of multiple contexts have been replaced with other interfaces.
|
||||
HIP provides a Context API to facilitate easy porting from existing Driver code.
|
||||
In HIP, the ``Ctx`` functions largely provide an alternate syntax for changing the active device.
|
||||
|
||||
Most new applications preferentially use ``hipSetDevice`` or the stream APIs. Therefore, HIP has marked the ``hipCtx`` APIs as **deprecated**. Support for these APIs might not be available in future releases. For more details on deprecated APIs, see :doc:`../reference/deprecated_api_list`.
|
||||
|
||||
HIP module and Ctx APIs
|
||||
================================================================================
|
||||
|
||||
Rather than present two separate APIs, HIP extends the HIP API with new APIs for
|
||||
modules and ``Ctx`` control.
|
||||
|
||||
hipModule API
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Like the CUDA driver API, the Module API provides additional control over how
|
||||
code is loaded, including options to load code from files or from in-memory
|
||||
pointers.
|
||||
NVCC and HIP-Clang target different architectures and use different code object
|
||||
formats. NVCC supports ``cubin`` or ``ptx`` files, while the HIP-Clang path uses
|
||||
the ``hsaco`` format.
|
||||
The external compilers which generate these code objects are responsible for
|
||||
generating and loading the correct code object for each platform.
|
||||
Notably, there is no fat binary format that can contain code for both NVCC and
|
||||
HIP-Clang platforms. The following table summarizes the formats used on each
|
||||
platform:
|
||||
|
||||
.. list-table:: Module formats
|
||||
:header-rows: 1
|
||||
|
||||
* - Format
|
||||
- APIs
|
||||
- NVCC
|
||||
- HIP-CLANG
|
||||
* - Code object
|
||||
- ``hipModuleLoad``, ``hipModuleLoadData``
|
||||
- ``.cubin`` or PTX text
|
||||
- ``.hsaco``
|
||||
* - Fat binary
|
||||
- ``hipModuleLoadFatBin``
|
||||
- ``.fatbin``
|
||||
- ``.hip_fatbin``
|
||||
|
||||
``hipcc`` uses HIP-Clang or NVCC to compile host code. Both of these compilers can embed code objects into the final executable. These code objects are automatically loaded when the application starts.
|
||||
The ``hipModule`` API can be used to load additional code objects. When used this way, it extends the capability of the automatically loaded code objects.
|
||||
HIP-Clang enables both of these capabilities to be used together. Of course, it is possible to create a program with no kernels and no automatic loading.
|
||||
|
||||
For module API reference, visit :ref:`module_management_reference`.
|
||||
|
||||
hipCtx API
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
HIP provides a ``Ctx`` API as a thin layer over the existing device functions. The ``Ctx`` API can be used to set the current context or to query properties of the device associated with the context.
|
||||
The current context is implicitly used by other APIs, such as ``hipStreamCreate``.
|
||||
|
||||
For context reference, visit :ref:`context_management_reference`.
|
||||
|
||||
HIPIFY translation of CUDA driver API
|
||||
================================================================================
|
||||
|
||||
The HIPIFY tools convert CUDA driver APIs such as streams, events, modules,
|
||||
devices, memory management, context, and the profiler to the equivalent HIP
|
||||
calls. For example, ``cuEventCreate`` is translated to :cpp:func:`hipEventCreate`.
|
||||
HIPIFY tools also convert error codes from the driver namespace and coding
|
||||
conventions to the equivalent HIP error code. HIP unifies the APIs for these
|
||||
common functions.
|
||||
|
||||
The memory copy API requires additional explanation. The CUDA driver includes
|
||||
the memory direction in the name of the API (``cuMemcpyHtoD``), while the CUDA
|
||||
runtime API provides a single memory copy API with a parameter that specifies
|
||||
the direction. It also supports a "default" direction where the runtime
|
||||
determines the direction automatically.
|
||||
HIP provides both versions, for example, :cpp:func:`hipMemcpyHtoD` as well as
|
||||
:cpp:func:`hipMemcpy`. The first version might be faster in some cases because
|
||||
it avoids any host overhead to detect the different memory directions.
|
||||
|
||||
HIP defines a single error space and uses camel case for all errors (i.e. ``hipErrorInvalidValue``).
|
||||
|
||||
For further information, visit the :doc:`hipify:index`.
|
||||
|
||||
Address spaces
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
HIP-Clang defines a process-wide address space where the CPU and all devices
|
||||
allocate addresses from a single unified pool.
|
||||
This means addresses can be shared between contexts. Unlike the original CUDA
|
||||
implementation, a new context does not create a new address space for the device.
|
||||
|
||||
Using hipModuleLaunchKernel
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Both CUDA driver and runtime APIs define a function for launching kernels,
|
||||
called ``cuLaunchKernel`` or ``cudaLaunchKernel``. The equivalent API in HIP is
|
||||
``hipModuleLaunchKernel``.
|
||||
The kernel arguments and the execution configuration (grid dimensions, group
|
||||
dimensions, dynamic shared memory, and stream) are passed as arguments to the
|
||||
launch function.
|
||||
The runtime API additionally provides the ``<<< >>>`` syntax for launching
|
||||
kernels, which resembles a special function call and is easier to use than the
|
||||
explicit launch API, especially when handling kernel arguments.
|
||||
However, this syntax is not standard C++ and is available only when NVCC is used
|
||||
to compile the host code.
|
||||
|
||||
Additional information
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
HIP-Clang creates a primary context when the HIP API is called. So, in pure
|
||||
driver API code, HIP-Clang creates a primary context while HIP/NVCC has an empty
|
||||
context stack. HIP-Clang pushes the primary context to the context stack when it
|
||||
is empty. This can lead to subtle differences in applications which mix the
|
||||
runtime and driver APIs.
|
||||
|
||||
HIP-Clang implementation notes
|
||||
================================================================================
|
||||
|
||||
.hip_fatbin
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
HIP-Clang links device code from different translation units together. For each
|
||||
device target, it generates a code object. ``clang-offload-bundler`` bundles
|
||||
code objects for different device targets into one fat binary, which is embedded
|
||||
as the global symbol ``__hip_fatbin`` in the ``.hip_fatbin`` section of the ELF
|
||||
file of the executable or shared object.
|
||||
|
||||
Initialization and termination functions
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
HIP-Clang generates initialization and termination functions for each
|
||||
translation unit for host code compilation. The initialization functions call
|
||||
``__hipRegisterFatBinary`` to register the fat binary embedded in the ELF file.
|
||||
They also call ``__hipRegisterFunction`` and ``__hipRegisterVar`` to register
|
||||
kernel functions and device-side global variables. The termination functions
|
||||
call ``__hipUnregisterFatBinary``.
|
||||
HIP-Clang emits a global variable ``__hip_gpubin_handle`` of type ``void**``
|
||||
with ``linkonce`` linkage and an initial value of 0 for each host translation
|
||||
unit. Each initialization function checks ``__hip_gpubin_handle`` and registers
|
||||
the fat binary only if ``__hip_gpubin_handle`` is 0. It saves the return value
|
||||
of ``__hip_gpubin_handle`` to ``__hip_gpubin_handle``. This ensures that the fat
|
||||
binary is registered once. A similar check is performed in the termination
|
||||
functions.
|
||||
|
||||
Kernel launching
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
HIP-Clang supports kernel launching using either the CUDA ``<<<>>>`` syntax,
|
||||
``hipLaunchKernel``, or ``hipLaunchKernelGGL``. The last option is a macro which
|
||||
expands to the CUDA ``<<<>>>`` syntax by default. It can also be turned into a
|
||||
template by defining ``HIP_TEMPLATE_KERNEL_LAUNCH``.
|
||||
|
||||
When the executable or shared library is loaded by the dynamic linker, the
|
||||
initialization functions are called. In the initialization functions, the code
|
||||
objects containing all kernels are loaded when ``__hipRegisterFatBinary`` is
|
||||
called. When ``__hipRegisterFunction`` is called, the stub functions are
|
||||
associated with the corresponding kernels in the code objects.
|
||||
|
||||
HIP-Clang implements two sets of APIs for launching kernels.
|
||||
By default, when HIP-Clang encounters the ``<<<>>>`` statement in the host code,
|
||||
it first calls ``hipConfigureCall`` to set up the threads and grids. It then
|
||||
calls the stub function with the given arguments. The stub function calls
|
||||
``hipSetupArgument`` for each kernel argument, then calls ``hipLaunchByPtr``
|
||||
with a function pointer to the stub function. In ``hipLaunchByPtr``, the actual
|
||||
kernel associated with the stub function is launched.
|
||||
|
||||
NVCC implementation notes
|
||||
================================================================================
|
||||
|
||||
Interoperation between HIP and CUDA driver
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
CUDA applications might want to mix CUDA driver code with HIP code (see the
|
||||
example below). This table shows the equivalence between CUDA and HIP types
|
||||
required to implement this interaction.
|
||||
|
||||
.. list-table:: Equivalence table between HIP and CUDA types
|
||||
:header-rows: 1
|
||||
|
||||
* - HIP type
|
||||
- CU Driver type
|
||||
- CUDA Runtime type
|
||||
* - ``hipModule_t``
|
||||
- ``CUmodule``
|
||||
-
|
||||
* - ``hipFunction_t``
|
||||
- ``CUfunction``
|
||||
-
|
||||
* - ``hipCtx_t``
|
||||
- ``CUcontext``
|
||||
-
|
||||
* - ``hipDevice_t``
|
||||
- ``CUdevice``
|
||||
-
|
||||
* - ``hipStream_t``
|
||||
- ``CUstream``
|
||||
- ``cudaStream_t``
|
||||
* - ``hipEvent_t``
|
||||
- ``CUevent``
|
||||
- ``cudaEvent_t``
|
||||
* - ``hipArray``
|
||||
- ``CUarray``
|
||||
- ``cudaArray``
|
||||
|
||||
Compilation options
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
The ``hipModule_t`` interface does not support the ``cuModuleLoadDataEx`` function, which is used to control PTX compilation options.
|
||||
HIP-Clang does not use PTX, so it does not support these compilation options.
|
||||
In fact, HIP-Clang code objects contain fully compiled code for a device-specific instruction set and don't require additional compilation as a part of the load step.
|
||||
The corresponding HIP function ``hipModuleLoadDataEx`` behaves like ``hipModuleLoadData`` on the HIP-Clang path (where compilation options are not used) and like ``cuModuleLoadDataEx`` on the NVCC path.
|
||||
|
||||
For example:
|
||||
|
||||
.. tab-set::
|
||||
|
||||
.. tab-item:: HIP
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
hipModule_t module;
|
||||
void *imagePtr = ...; // Somehow populate data pointer with code object
|
||||
|
||||
const int numOptions = 1;
|
||||
hipJitOption options[numOptions];
|
||||
void *optionValues[numOptions];
|
||||
|
||||
options[0] = hipJitOptionMaxRegisters;
|
||||
unsigned maxRegs = 15;
|
||||
optionValues[0] = (void *)(&maxRegs);
|
||||
|
||||
// hipModuleLoadData(module, imagePtr) will be called on HIP-Clang path, JIT
|
||||
// options will not be used, and cupModuleLoadDataEx(module, imagePtr,
|
||||
// numOptions, options, optionValues) will be called on NVCC path
|
||||
hipModuleLoadDataEx(module, imagePtr, numOptions, options, optionValues);
|
||||
|
||||
hipFunction_t k;
|
||||
hipModuleGetFunction(&k, module, "myKernel");
|
||||
|
||||
.. tab-item:: CUDA
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
CUmodule module;
|
||||
void *imagePtr = ...; // Somehow populate data pointer with code object
|
||||
|
||||
const int numOptions = 1;
|
||||
CUJit_option options[numOptions];
|
||||
void *optionValues[numOptions];
|
||||
|
||||
options[0] = CU_JIT_MAX_REGISTERS;
|
||||
unsigned maxRegs = 15;
|
||||
optionValues[0] = (void *)(&maxRegs);
|
||||
|
||||
cuModuleLoadDataEx(module, imagePtr, numOptions, options, optionValues);
|
||||
|
||||
CUfunction k;
|
||||
cuModuleGetFunction(&k, module, "myKernel");
|
||||
|
||||
The sample below shows how to use ``hipModuleGetFunction``.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <hip/hip_runtime_api.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
int main() {
|
||||
|
||||
size_t elements = 64*1024;
|
||||
size_t size_bytes = elements * sizeof(float);
|
||||
|
||||
std::vector<float> A(elements), B(elements);
|
||||
|
||||
// On NVIDIA platforms the driver runtime needs to be initiated
|
||||
#ifdef __HIP_PLATFORM_NVIDIA__
|
||||
hipInit(0);
|
||||
hipDevice_t device;
|
||||
hipCtx_t context;
|
||||
HIPCHECK(hipDeviceGet(&device, 0));
|
||||
HIPCHECK(hipCtxCreate(&context, 0, device));
|
||||
#endif
|
||||
|
||||
// Allocate device memory
|
||||
hipDeviceptr_t d_A, d_B;
|
||||
HIPCHECK(hipMalloc(&d_A, size_bytes));
|
||||
HIPCHECK(hipMalloc(&d_B, size_bytes));
|
||||
|
||||
// Copy data to device
|
||||
HIPCHECK(hipMemcpyHtoD(d_A, A.data(), size_bytes));
|
||||
HIPCHECK(hipMemcpyHtoD(d_B, B.data(), size_bytes));
|
||||
|
||||
// Load module
|
||||
hipModule_t Module;
|
||||
// For AMD the module file has to contain architecture specific object codee
|
||||
// For NVIDIA the module file has to contain PTX, found in e.g. "vcpy_isa.ptx"
|
||||
HIPCHECK(hipModuleLoad(&Module, "vcpy_isa.co"));
|
||||
// Get kernel function from the module via its name
|
||||
hipFunction_t Function;
|
||||
HIPCHECK(hipModuleGetFunction(&Function, Module, "hello_world"));
|
||||
|
||||
// Create buffer for kernel arguments
|
||||
std::vector<void*> argBuffer{&d_A, &d_B};
|
||||
size_t arg_size_bytes = argBuffer.size() * sizeof(void*);
|
||||
|
||||
// Create configuration passed to the kernel as arguments
|
||||
void* config[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, argBuffer.data(),
|
||||
HIP_LAUNCH_PARAM_BUFFER_SIZE, &arg_size_bytes, HIP_LAUNCH_PARAM_END};
|
||||
|
||||
int threads_per_block = 128;
|
||||
int blocks = (elements + threads_per_block - 1) / threads_per_block;
|
||||
|
||||
// Actually launch kernel
|
||||
HIPCHECK(hipModuleLaunchKernel(Function, blocks, 1, 1, threads_per_block, 1, 1, 0, 0, NULL, config));
|
||||
|
||||
HIPCHECK(hipMemcpyDtoH(A.data(), d_A, elements));
|
||||
HIPCHECK(hipMemcpyDtoH(B.data(), d_B, elements));
|
||||
|
||||
#ifdef __HIP_PLATFORM_NVIDIA__
|
||||
HIPCHECK(hipCtxDetach(context));
|
||||
#endif
|
||||
|
||||
HIPCHECK(hipFree(d_A));
|
||||
HIPCHECK(hipFree(d_B));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
HIP module and texture Driver API
|
||||
================================================================================
|
||||
|
||||
HIP supports texture driver APIs. However, texture references must be declared
|
||||
within the host scope. The following code demonstrates the use of texture
|
||||
references for the ``__HIP_PLATFORM_AMD__`` platform.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// Code to generate code object
|
||||
|
||||
#include "hip/hip_runtime.h"
|
||||
extern texture<float, 2, hipReadModeElementType> tex;
|
||||
|
||||
__global__ void tex2dKernel(hipLaunchParm lp, float *outputData, int width,
|
||||
int height) {
|
||||
int x = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
int y = blockIdx.y * blockDim.y + threadIdx.y;
|
||||
outputData[y * width + x] = tex2D(tex, x, y);
|
||||
}
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// Host code:
|
||||
|
||||
texture<float, 2, hipReadModeElementType> tex;
|
||||
|
||||
void myFunc ()
|
||||
{
|
||||
// ...
|
||||
|
||||
textureReference* texref;
|
||||
hipModuleGetTexRef(&texref, Module1, "tex");
|
||||
hipTexRefSetAddressMode(texref, 0, hipAddressModeWrap);
|
||||
hipTexRefSetAddressMode(texref, 1, hipAddressModeWrap);
|
||||
hipTexRefSetFilterMode(texref, hipFilterModePoint);
|
||||
hipTexRefSetFlags(texref, 0);
|
||||
hipTexRefSetFormat(texref, HIP_AD_FORMAT_FLOAT, 1);
|
||||
hipTexRefSetArray(texref, array, HIP_TRSA_OVERRIDE_FORMAT);
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
Driver entry point access
|
||||
================================================================================
|
||||
|
||||
Starting from HIP version 6.2.0, support for Driver Entry Point Access is
|
||||
available when using CUDA 12.0 or newer. This feature allows developers to
|
||||
directly interact with the CUDA driver API, providing more control over GPU
|
||||
operations.
|
||||
|
||||
Driver Entry Point Access provides several features:
|
||||
|
||||
* Retrieving the address of a runtime function
|
||||
* Requesting the default stream version on a per-thread basis
|
||||
* Accessing new HIP features on older toolkits with a newer driver
|
||||
|
||||
For driver entry point access reference, visit :cpp:func:`hipGetProcAddress`.
|
||||
|
||||
Address retrieval
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
The :cpp:func:`hipGetProcAddress` function can be used to obtain the address of
|
||||
a runtime function. This is demonstrated in the following example:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <hip/hip_runtime_api.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
typedef hipError_t (*hipInit_t)(unsigned int);
|
||||
|
||||
int main() {
|
||||
// Initialize the HIP runtime
|
||||
hipError_t res = hipInit(0);
|
||||
if (res != hipSuccess) {
|
||||
std::cerr << "Failed to initialize HIP runtime." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get the address of the hipInit function
|
||||
hipInit_t hipInitFunc;
|
||||
int hipVersion = HIP_VERSION; // Use the HIP version defined in hip_runtime_api.h
|
||||
uint64_t flags = 0; // No special flags
|
||||
hipDriverProcAddressQueryResult symbolStatus;
|
||||
|
||||
res = hipGetProcAddress("hipInit", (void**)&hipInitFunc, hipVersion, flags, &symbolStatus);
|
||||
if (res != hipSuccess) {
|
||||
std::cerr << "Failed to get address of hipInit()." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Call the hipInit function using the obtained address
|
||||
res = hipInitFunc(0);
|
||||
if (res == hipSuccess) {
|
||||
std::cout << "HIP runtime initialized successfully using hipGetProcAddress()." << std::endl;
|
||||
} else {
|
||||
std::cerr << "Failed to initialize HIP runtime using hipGetProcAddress()." << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Per-thread default stream version request
|
||||
================================================================================
|
||||
|
||||
HIP offers functionality similar to CUDA for managing streams on a per-thread
|
||||
basis. By using ``hipStreamPerThread``, each thread can independently manage its
|
||||
default stream, simplifying operations. The following example demonstrates how
|
||||
this feature enhances performance by reducing contention and improving
|
||||
efficiency.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
// Initialize the HIP runtime
|
||||
hipError_t res = hipInit(0);
|
||||
if (res != hipSuccess) {
|
||||
std::cerr << "Failed to initialize HIP runtime." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get the per-thread default stream
|
||||
hipStream_t stream = hipStreamPerThread;
|
||||
|
||||
// Use the stream for some operation
|
||||
// For example, allocate memory on the device
|
||||
void* d_ptr;
|
||||
size_t size = 1024;
|
||||
res = hipMalloc(&d_ptr, size);
|
||||
if (res != hipSuccess) {
|
||||
std::cerr << "Failed to allocate memory." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Perform some operation using the stream
|
||||
// For example, set memory on the device
|
||||
res = hipMemsetAsync(d_ptr, 0, size, stream);
|
||||
if (res != hipSuccess) {
|
||||
std::cerr << "Failed to set memory." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Synchronize the stream
|
||||
res = hipStreamSynchronize(stream);
|
||||
if (res != hipSuccess) {
|
||||
std::cerr << "Failed to synchronize stream." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << "Operation completed successfully using per-thread default stream." << std::endl;
|
||||
|
||||
// Free the allocated memory
|
||||
hipFree(d_ptr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Accessing new HIP features with a newer driver
|
||||
================================================================================
|
||||
|
||||
HIP is designed to be forward compatible, allowing newer features to be utilized
|
||||
with older toolkits, provided a compatible driver is present. Feature support
|
||||
can be verified through runtime API functions and version checks. This approach
|
||||
ensures that applications can benefit from new features and improvements in the
|
||||
HIP runtime without needing to be recompiled with a newer toolkit. The function
|
||||
:cpp:func:`hipGetProcAddress` enables dynamic querying and the use of newer
|
||||
functions offered by the HIP runtime, even if the application was built with an
|
||||
older toolkit.
|
||||
|
||||
An example is provided for a hypothetical ``foo()`` function.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// Get the address of the foo function
|
||||
foo_t fooFunc;
|
||||
int hipVersion = 60300000; // Use an own HIP version number (e.g. 6.3.0)
|
||||
uint64_t flags = 0; // No special flags
|
||||
hipDriverProcAddressQueryResult symbolStatus;
|
||||
|
||||
res = hipGetProcAddress("foo", (void**)&fooFunc, hipVersion, flags, &symbolStatus);
|
||||
|
||||
The HIP version number is defined as an integer:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
HIP_VERSION=HIP_VERSION_MAJOR * 10000000 + HIP_VERSION_MINOR * 100000 + HIP_VERSION_PATCH
|
||||
|
||||
CU_POINTER_ATTRIBUTE_MEMORY_TYPE
|
||||
================================================================================
|
||||
|
||||
To get the pointer's memory type in HIP, developers should use
|
||||
:cpp:func:`hipPointerGetAttributes`. First parameter of the function is
|
||||
`hipPointerAttribute_t`. Its ``type`` member variable indicates whether the
|
||||
memory pointed to is allocated on the device or the host.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
double * ptr;
|
||||
hipMalloc(&ptr, sizeof(double));
|
||||
hipPointerAttribute_t attr;
|
||||
hipPointerGetAttributes(&attr, ptr); /*attr.type is hipMemoryTypeDevice*/
|
||||
if(attr.type == hipMemoryTypeDevice)
|
||||
std::cout << "ptr is of type hipMemoryTypeDevice" << std::endl;
|
||||
|
||||
double* ptrHost;
|
||||
hipHostMalloc(&ptrHost, sizeof(double));
|
||||
hipPointerAttribute_t attr;
|
||||
hipPointerGetAttributes(&attr, ptrHost); /*attr.type is hipMemoryTypeHost*/
|
||||
if(attr.type == hipMemorTypeHost)
|
||||
std::cout << "ptrHost is of type hipMemoryTypeHost" << std::endl;
|
||||
|
||||
Note that ``hipMemoryType`` enum values are different from the
|
||||
``cudaMemoryType`` enum values.
|
||||
|
||||
For example, on AMD platform, `hipMemoryType` is defined in `hip_runtime_api.h`,
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
typedef enum hipMemoryType {
|
||||
hipMemoryTypeHost = 0, ///< Memory is physically located on host
|
||||
hipMemoryTypeDevice = 1, ///< Memory is physically located on device. (see deviceId for specific device)
|
||||
hipMemoryTypeArray = 2, ///< Array memory, physically located on device. (see deviceId for specific device)
|
||||
hipMemoryTypeUnified = 3, ///< Not used currently
|
||||
hipMemoryTypeManaged = 4 ///< Managed memory, automaticallly managed by the unified memory system
|
||||
} hipMemoryType;
|
||||
|
||||
Looking into CUDA toolkit, it defines `cudaMemoryType` as following,
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
enum cudaMemoryType
|
||||
{
|
||||
cudaMemoryTypeUnregistered = 0, // Unregistered memory.
|
||||
cudaMemoryTypeHost = 1, // Host memory.
|
||||
cudaMemoryTypeDevice = 2, // Device memory.
|
||||
cudaMemoryTypeManaged = 3, // Managed memory
|
||||
}
|
||||
|
||||
In this case, memory type translation for ``hipPointerGetAttributes`` needs to
|
||||
be handled properly on NVIDIA platform to get the correct memory type in CUDA,
|
||||
which is done in the file ``nvidia_hip_runtime_api.h``.
|
||||
|
||||
So in any HIP applications which use HIP APIs involving memory types, developers
|
||||
should use ``#ifdef`` in order to assign the correct enum values depending on
|
||||
NVIDIA or AMD platform.
|
||||
|
||||
As an example, please see the code from the `link <https://github.com/ROCm/hip-tests/tree/develop/catch/unit/memory/hipMemcpyParam2D.cc>`_.
|
||||
|
||||
With the ``#ifdef`` condition, HIP APIs work as expected on both AMD and NVIDIA
|
||||
platforms.
|
||||
|
||||
Note, ``cudaMemoryTypeUnregistered`` is currently not supported as
|
||||
``hipMemoryType`` enum, due to HIP functionality backward compatibility.
|
||||
@@ -0,0 +1,649 @@
|
||||
.. meta::
|
||||
:description: This chapter presents how to port CUDA source code to HIP.
|
||||
:keywords: AMD, ROCm, HIP, CUDA, porting, port
|
||||
|
||||
********************************************************************************
|
||||
HIP porting guide
|
||||
********************************************************************************
|
||||
|
||||
HIP is designed to ease the porting of existing CUDA code into the HIP
|
||||
environment. This page describes the available tools and provides practical
|
||||
suggestions on how to port CUDA code and work through common issues.
|
||||
|
||||
Porting a CUDA Project
|
||||
================================================================================
|
||||
|
||||
Mixing HIP and CUDA code results in valid CUDA code. This enables users to
|
||||
incrementally port CUDA to HIP, and still compile and test the code during the
|
||||
transition.
|
||||
|
||||
The only notable exception is ``hipError_t``, which is not just an alias to
|
||||
``cudaError_t``. In these cases HIP provides functions to convert between the
|
||||
error code spaces:
|
||||
|
||||
* :cpp:func:`hipErrorToCudaError`
|
||||
* :cpp:func:`hipErrorToCUResult`
|
||||
* :cpp:func:`hipCUDAErrorTohipError`
|
||||
* :cpp:func:`hipCUResultTohipError`
|
||||
|
||||
General Tips
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
* Starting to port on an NVIDIA machine is often the easiest approach, as the
|
||||
code can be tested for functionality and performance even if not fully ported
|
||||
to HIP.
|
||||
* Once the CUDA code is ported to HIP and is running on the CUDA machine,
|
||||
compile the HIP code for an AMD machine.
|
||||
* You can handle platform-specific features through conditional compilation or
|
||||
by adding them to the open-source HIP infrastructure.
|
||||
* Use the `HIPIFY <https://github.com/ROCm/HIPIFY>`_ tools to automatically
|
||||
convert CUDA code to HIP, as described in the following section.
|
||||
|
||||
HIPIFY
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
:doc:`HIPIFY <hipify:index>` is a collection of tools that automatically
|
||||
translate CUDA to HIP code. There are two flavours available, ``hipfiy-clang``
|
||||
and ``hipify-perl``.
|
||||
|
||||
:doc:`hipify-clang <hipify:hipify-clang>` is, as the name implies, a Clang-based
|
||||
tool, and actually parses the code, translates it into an Abstract Syntax Tree,
|
||||
from which it then generates the HIP source. For this, ``hipify-clang`` needs to
|
||||
be able to actually compile the code, so the CUDA code needs to be correct, and
|
||||
a CUDA install with all necessary headers must be provided.
|
||||
|
||||
:doc:`hipify-perl <hipify:hipify-perl>` uses pattern matching, to translate the
|
||||
CUDA code to HIP. It does not require a working CUDA installation, and can also
|
||||
convert CUDA code, that is not syntactically correct. It is therefore easier to
|
||||
set up and use, but is not as powerful as ``hipfiy-clang``.
|
||||
|
||||
Scanning existing CUDA code to scope the porting effort
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
The ``--examine`` option, supported by the clang and perl version, tells hipify
|
||||
to do a test-run, without changing the files, but instead scan CUDA code to
|
||||
determine which files contain CUDA code and how much of that code can
|
||||
automatically be hipified.
|
||||
|
||||
There also are ``hipexamine-perl.sh`` or ``hipexamine.sh`` (for
|
||||
``hipify-clang``) scripts to automatically scan directories.
|
||||
|
||||
For example, the following is a scan of one of the
|
||||
`cuda-samples <https://github.com/NVIDIA/cuda-samples>`_:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
> cd Samples/2_Concepts_and_Techniques/convolutionSeparable/
|
||||
> hipexamine-perl.sh
|
||||
[HIPIFY] info: file './convolutionSeparable.cu' statistics:
|
||||
CONVERTED refs count: 2
|
||||
TOTAL lines of code: 214
|
||||
WARNINGS: 0
|
||||
[HIPIFY] info: CONVERTED refs by names:
|
||||
cooperative_groups.h => hip/hip_cooperative_groups.h: 1
|
||||
cudaMemcpyToSymbol => hipMemcpyToSymbol: 1
|
||||
|
||||
[HIPIFY] info: file './main.cpp' statistics:
|
||||
CONVERTED refs count: 13
|
||||
TOTAL lines of code: 174
|
||||
WARNINGS: 0
|
||||
[HIPIFY] info: CONVERTED refs by names:
|
||||
cudaDeviceSynchronize => hipDeviceSynchronize: 2
|
||||
cudaFree => hipFree: 3
|
||||
cudaMalloc => hipMalloc: 3
|
||||
cudaMemcpy => hipMemcpy: 2
|
||||
cudaMemcpyDeviceToHost => hipMemcpyDeviceToHost: 1
|
||||
cudaMemcpyHostToDevice => hipMemcpyHostToDevice: 1
|
||||
cuda_runtime.h => hip/hip_runtime.h: 1
|
||||
|
||||
[HIPIFY] info: file 'GLOBAL' statistics:
|
||||
CONVERTED refs count: 15
|
||||
TOTAL lines of code: 512
|
||||
WARNINGS: 0
|
||||
[HIPIFY] info: CONVERTED refs by names:
|
||||
cooperative_groups.h => hip/hip_cooperative_groups.h: 1
|
||||
cudaDeviceSynchronize => hipDeviceSynchronize: 2
|
||||
cudaFree => hipFree: 3
|
||||
cudaMalloc => hipMalloc: 3
|
||||
cudaMemcpy => hipMemcpy: 2
|
||||
cudaMemcpyDeviceToHost => hipMemcpyDeviceToHost: 1
|
||||
cudaMemcpyHostToDevice => hipMemcpyHostToDevice: 1
|
||||
cudaMemcpyToSymbol => hipMemcpyToSymbol: 1
|
||||
cuda_runtime.h => hip/hip_runtime.h: 1
|
||||
|
||||
``hipexamine-perl.sh`` reports how many CUDA calls are going to be converted to
|
||||
HIP (e.g. ``CONVERTED refs count: 2``), and lists them by name together with
|
||||
their corresponding HIP-version (see the lines following ``[HIPIFY] info:
|
||||
CONVERTED refs by names:``). It also lists the total lines of code for the file
|
||||
and potential warnings. In the end it prints a summary for all files.
|
||||
|
||||
Automatically converting a CUDA project
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
To directly replace the files, the ``--inplace`` option of ``hipify-perl`` or
|
||||
``hipify-clang`` can be used. This creates a backup of the original files in a
|
||||
``<filename>.prehip`` file and overwrites the existing files, keeping their file
|
||||
endings. If the ``--inplace`` option is not given, the scripts print the
|
||||
hipified code to ``stdout``.
|
||||
|
||||
``hipconvertinplace.sh``or ``hipconvertinplace-perl.sh`` operate on whole
|
||||
directories.
|
||||
|
||||
Library Equivalents
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
ROCm provides libraries to ease porting of code relying on CUDA libraries.
|
||||
Most CUDA libraries have a corresponding HIP library.
|
||||
|
||||
There are two flavours of libraries provided by ROCm, ones prefixed with ``hip``
|
||||
and ones prefixed with ``roc``. While both are written using HIP, in general
|
||||
only the ``hip``-libraries are portable. The libraries with the ``roc``-prefix
|
||||
might also run on CUDA-capable GPUs, however they have been optimized for AMD
|
||||
GPUs and might use assembly code or a different API, to achieve the best
|
||||
performance.
|
||||
|
||||
.. note::
|
||||
|
||||
If the application is only required to run on AMD GPUs, it is recommended to
|
||||
use the ``roc``-libraries.
|
||||
|
||||
In the case where a library provides a ``roc``- and a ``hip``- version, the
|
||||
``hip`` version is a marshalling library, which is just a thin layer that is
|
||||
redirecting the function calls to either the ``roc``-library or the
|
||||
corresponding CUDA library, depending on the platform, to provide compatibility.
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
|
||||
*
|
||||
- CUDA Library
|
||||
- ``hip`` Library
|
||||
- ``roc`` Library
|
||||
- Comment
|
||||
*
|
||||
- cuBLAS
|
||||
- `hipBLAS <https://github.com/ROCm/hipBLAS>`_
|
||||
- `rocBLAS <https://github.com/ROCm/rocBLAS>`_
|
||||
- Basic Linear Algebra Subroutines
|
||||
*
|
||||
- cuBLASLt
|
||||
- `hipBLASLt <https://github.com/ROCm/hipBLASLt>`_
|
||||
-
|
||||
- Linear Algebra Subroutines, lightweight and new flexible API
|
||||
*
|
||||
- cuFFT
|
||||
- `hipFFT <https://github.com/ROCm/hipFFT>`_
|
||||
- `rocFFT <https://github.com/ROCm/rocfft>`_
|
||||
- Fast Fourier Transfer Library
|
||||
*
|
||||
- cuSPARSE
|
||||
- `hipSPARSE <https://github.com/ROCm/hipSPARSE>`_
|
||||
- `rocSPARSE <https://github.com/ROCm/rocSPARSE>`_
|
||||
- Sparse BLAS + SPMV
|
||||
*
|
||||
- cuSOLVER
|
||||
- `hipSOLVER <https://github.com/ROCm/hipsolver>`_
|
||||
- `rocSOLVER <https://github.com/ROCm/rocsolver>`_
|
||||
- Lapack library
|
||||
*
|
||||
- AmgX
|
||||
-
|
||||
- `rocALUTION <https://github.com/ROCm/rocalution>`_
|
||||
- Sparse iterative solvers and preconditioners with algebraic multigrid
|
||||
*
|
||||
- Thrust
|
||||
-
|
||||
- `rocThrust <https://github.com/ROCm/rocThrust>`_
|
||||
- C++ parallel algorithms library
|
||||
*
|
||||
- CUB
|
||||
- `hipCUB <https://github.com/ROCm/hipcub>`_
|
||||
- `rocPRIM <https://github.com/ROCm/rocPRIM>`_
|
||||
- Low Level Optimized Parallel Primitives
|
||||
*
|
||||
- cuDNN
|
||||
-
|
||||
- `MIOpen <https://github.com/ROCm/MIOpen>`_
|
||||
- Deep learning Solver Library
|
||||
*
|
||||
- cuRAND
|
||||
- `hipRAND <https://github.com/ROCm/hiprand>`_
|
||||
- `rocRAND <https://github.com/ROCm/rocrand>`_
|
||||
- Random Number Generator Library
|
||||
*
|
||||
- NCCL
|
||||
-
|
||||
- `RCCL <https://github.com/ROCm/rccl>`_
|
||||
- Communications Primitives Library based on the MPI equivalents
|
||||
RCCL is a drop-in replacement for NCCL
|
||||
|
||||
Distinguishing compilers and platforms
|
||||
================================================================================
|
||||
|
||||
Identifying the HIP Target Platform
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
HIP projects can target either the AMD or NVIDIA platform. The platform affects
|
||||
which backend-headers are included and which libraries are used for linking. The
|
||||
created binaries are not portable between AMD and NVIDIA platforms.
|
||||
|
||||
To write code that is specific to a platform the C++-macros specified in the
|
||||
following section can be used.
|
||||
|
||||
Compiler Defines: Summary
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
This section lists macros that are defined by compilers and the HIP/CUDA APIs,
|
||||
and what compiler/platform combinations they are defined for.
|
||||
|
||||
The following table lists the macros that can be used when compiling HIP. Most
|
||||
of these macros are not directly defined by the compilers, but in
|
||||
``hip_common.h``, which is included by ``hip_runtime.h``.
|
||||
|
||||
.. list-table:: HIP-related defines
|
||||
:header-rows: 1
|
||||
|
||||
*
|
||||
- Macro
|
||||
- ``amdclang++``
|
||||
- ``nvcc`` when used as backend for ``hipcc``
|
||||
- Other (GCC, ICC, Clang, etc.)
|
||||
*
|
||||
- ``__HIP_PLATFORM_AMD__``
|
||||
- Defined
|
||||
- Undefined
|
||||
- Undefined, needs to be set explicitly
|
||||
*
|
||||
- ``__HIP_PLATFORM_NVIDIA__``
|
||||
- Undefined
|
||||
- Defined
|
||||
- Undefined, needs to be set explicitly
|
||||
*
|
||||
- ``__HIPCC__``
|
||||
- Defined when compiling ``.hip`` files or specifying ``-x hip``
|
||||
- Defined when compiling ``.hip`` files or specifying ``-x hip``
|
||||
- Undefined
|
||||
*
|
||||
- ``__HIP_DEVICE_COMPILE__``
|
||||
- 1 if compiling for device
|
||||
undefined if compiling for host
|
||||
- 1 if compiling for device
|
||||
undefined if compiling for host
|
||||
- Undefined
|
||||
*
|
||||
- ``__HIP_ARCH_<FEATURE>__``
|
||||
- 0 or 1 depending on feature support of targeted hardware (see :ref:`identifying_device_architecture_features`)
|
||||
- 0 or 1 depending on feature support of targeted hardware
|
||||
- 0
|
||||
*
|
||||
- ``__HIP__``
|
||||
- Defined when compiling ``.hip`` files or specifying ``-x hip``
|
||||
- Undefined
|
||||
- Undefined
|
||||
|
||||
The following table lists macros related to ``nvcc`` and CUDA as HIP backend.
|
||||
|
||||
.. list-table:: NVCC-related defines
|
||||
:header-rows: 1
|
||||
|
||||
*
|
||||
- Macro
|
||||
- ``amdclang++``
|
||||
- ``nvcc`` when used as backend for ``hipcc``
|
||||
- Other (GCC, ICC, Clang, etc.)
|
||||
*
|
||||
- ``__CUDACC__``
|
||||
- Undefined
|
||||
- Defined
|
||||
- Undefined
|
||||
(Clang defines this when explicitly compiling CUDA code)
|
||||
*
|
||||
- ``__NVCC__``
|
||||
- Undefined
|
||||
- Defined
|
||||
- Undefined
|
||||
*
|
||||
- ``__CUDA_ARCH__`` [#cuda_arch]_
|
||||
- Undefined
|
||||
- Defined in device code
|
||||
Integer representing compute capability
|
||||
Must not be used in host code
|
||||
- Undefined
|
||||
|
||||
.. [#cuda_arch] the use of ``__CUDA_ARCH__`` to check for hardware features is
|
||||
discouraged, as this is not portable. Use the ``__HIP_ARCH_HAS_<FEATURE>``
|
||||
macros instead.
|
||||
|
||||
Identifying the compilation target platform
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Despite HIP's portability, it can be necessary to tailor code to a specific
|
||||
platform, in order to provide platform-specific code, or aid in
|
||||
platform-specific performance improvements.
|
||||
|
||||
For this, the ``__HIP_PLATFORM_AMD__`` and ``__HIP_PLATFORM_NVIDIA__`` macros
|
||||
can be used, e.g.:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#ifdef __HIP_PLATFORM_AMD__
|
||||
// This code path is compiled when amdclang++ is used for compilation
|
||||
#endif
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#ifdef __HIP_PLATFORM_NVIDIA__
|
||||
// This code path is compiled when nvcc is used for compilation
|
||||
// Could be compiling with CUDA language extensions enabled (for example, a ".cu file)
|
||||
// Could be in pass-through mode to an underlying host compiler (for example, a .cpp file)
|
||||
#endif
|
||||
|
||||
When using ``hipcc``, the environment variable ``HIP_PLATFORM`` specifies the
|
||||
runtime to use. When an AMD graphics driver and an AMD GPU is detected,
|
||||
``HIP_PLATFORM`` is set to ``amd``. If both runtimes are installed, and a
|
||||
specific one should be used, or ``hipcc`` can't detect the runtime, the
|
||||
environment variable has to be set manually.
|
||||
|
||||
To explicitly use the CUDA compilation path, use:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
export HIP_PLATFORM=nvidia
|
||||
hipcc main.cpp
|
||||
|
||||
Identifying Host or Device Compilation Pass
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
``amdclang++`` makes multiple passes over the code: one for the host code, and
|
||||
one each for the device code for every GPU architecture to be compiled for.
|
||||
``nvcc`` makes two passes over the code: one for host code and one for device
|
||||
code.
|
||||
|
||||
The ``__HIP_DEVICE_COMPILE__``-macro is defined when the compiler is compiling
|
||||
for the device.
|
||||
|
||||
|
||||
``__HIP_DEVICE_COMPILE__`` is a portable check that can replace the
|
||||
``__CUDA_ARCH__``.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include "hip/hip_runtime.h"
|
||||
#include <iostream>
|
||||
|
||||
__host__ __device__ void call_func(){
|
||||
#ifdef __HIP_DEVICE_COMPILE__
|
||||
printf("device\n");
|
||||
#else
|
||||
std::cout << "host" << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
__global__ void test_kernel(){
|
||||
call_func();
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
test_kernel<<<1, 1, 0, 0>>>();
|
||||
|
||||
call_func();
|
||||
}
|
||||
|
||||
.. _identifying_device_architecture_features:
|
||||
|
||||
Identifying Device Architecture Features
|
||||
================================================================================
|
||||
|
||||
GPUs of different generations and architectures do not all provide the same
|
||||
level of :doc:`hardware feature support <../reference/hardware_features>`. To
|
||||
guard device-code using these architecture dependent features, the
|
||||
``__HIP_ARCH_<FEATURE>__`` C++-macros can be used.
|
||||
|
||||
Device Code Feature Identification
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Some CUDA code tests ``__CUDA_ARCH__`` for a specific value to determine whether
|
||||
the GPU supports a certain architectural feature, depending on its compute
|
||||
capability. This requires knowledge about what ``__CUDA_ARCH__`` supports what
|
||||
feature set.
|
||||
|
||||
HIP simplifies this, by replacing these macros with feature-specific macros, not
|
||||
architecture specific.
|
||||
|
||||
For instance,
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
//#if __CUDA_ARCH__ >= 130 // does not properly specify, what feature is required, not portable
|
||||
#if __HIP_ARCH_HAS_DOUBLES__ == 1 // explicitly specifies, what feature is required, portable between AMD and NVIDIA GPUs
|
||||
// device code
|
||||
#endif
|
||||
|
||||
For host code, the ``__HIP_ARCH_<FEATURE>__`` defines are set to 0, if
|
||||
``hip_runtime.h`` is included, and undefined otherwise. It should not be relied
|
||||
upon in host code.
|
||||
|
||||
Host Code Feature Identification
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Host code must not rely on the ``__HIP_ARCH_<FEATURE>__`` macros, as the GPUs
|
||||
available to a system can not be known during compile time, and their
|
||||
architectural features differ.
|
||||
|
||||
Host code can query architecture feature flags during runtime, by using
|
||||
:cpp:func:`hipGetDeviceProperties` or :cpp:func:`hipDeviceGetAttribute`.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
#define HIP_CHECK(expression) { \
|
||||
const hipError_t err = expression; \
|
||||
if (err != hipSuccess){ \
|
||||
std::cout << "HIP Error: " << hipGetErrorString(err)) \
|
||||
<< " at line " << __LINE__ << std::endl; \
|
||||
std::exit(EXIT_FAILURE); \
|
||||
} \
|
||||
}
|
||||
|
||||
int main(){
|
||||
int deviceCount;
|
||||
HIP_CHECK(hipGetDeviceCount(&deviceCount));
|
||||
|
||||
int device = 0; // Query first available GPU. Can be replaced with any
|
||||
// integer up to, not including, deviceCount
|
||||
hipDeviceProp_t deviceProp;
|
||||
HIP_CHECK(hipGetDeviceProperties(&deviceProp, device));
|
||||
|
||||
std::cout << "The queried device ";
|
||||
if (deviceProp.arch.hasSharedInt32Atomics) // portable HIP feature query
|
||||
std::cout << "supports";
|
||||
else
|
||||
std::cout << "does not support";
|
||||
std::cout << " shared int32 atomic operations" << std::endl;
|
||||
}
|
||||
|
||||
Table of Architecture Properties
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
The table below shows the full set of architectural properties that HIP
|
||||
supports, together with the corresponding macros and device properties.
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
|
||||
*
|
||||
- Macro (for device code)
|
||||
- Device Property (host runtime query)
|
||||
- Comment
|
||||
*
|
||||
- ``__HIP_ARCH_HAS_GLOBAL_INT32_ATOMICS__``
|
||||
- ``hasGlobalInt32Atomics``
|
||||
- 32-bit integer atomics for global memory
|
||||
*
|
||||
- ``__HIP_ARCH_HAS_GLOBAL_FLOAT_ATOMIC_EXCH__``
|
||||
- ``hasGlobalFloatAtomicExch``
|
||||
- 32-bit float atomic exchange for global memory
|
||||
*
|
||||
- ``__HIP_ARCH_HAS_SHARED_INT32_ATOMICS__``
|
||||
- ``hasSharedInt32Atomics``
|
||||
- 32-bit integer atomics for shared memory
|
||||
*
|
||||
- ``__HIP_ARCH_HAS_SHARED_FLOAT_ATOMIC_EXCH__``
|
||||
- ``hasSharedFloatAtomicExch``
|
||||
- 32-bit float atomic exchange for shared memory
|
||||
*
|
||||
- ``__HIP_ARCH_HAS_FLOAT_ATOMIC_ADD__``
|
||||
- ``hasFloatAtomicAdd``
|
||||
- 32-bit float atomic add in global and shared memory
|
||||
*
|
||||
- ``__HIP_ARCH_HAS_GLOBAL_INT64_ATOMICS__``
|
||||
- ``hasGlobalInt64Atomics``
|
||||
- 64-bit integer atomics for global memory
|
||||
*
|
||||
- ``__HIP_ARCH_HAS_SHARED_INT64_ATOMICS__``
|
||||
- ``hasSharedInt64Atomics``
|
||||
- 64-bit integer atomics for shared memory
|
||||
*
|
||||
- ``__HIP_ARCH_HAS_DOUBLES__``
|
||||
- ``hasDoubles``
|
||||
- Double-precision floating-point operations
|
||||
*
|
||||
- ``__HIP_ARCH_HAS_WARP_VOTE__``
|
||||
- ``hasWarpVote``
|
||||
- Warp vote instructions (``any``, ``all``)
|
||||
*
|
||||
- ``__HIP_ARCH_HAS_WARP_BALLOT__``
|
||||
- ``hasWarpBallot``
|
||||
- Warp ballot instructions
|
||||
*
|
||||
- ``__HIP_ARCH_HAS_WARP_SHUFFLE__``
|
||||
- ``hasWarpShuffle``
|
||||
- Warp shuffle operations (``shfl_*``)
|
||||
*
|
||||
- ``__HIP_ARCH_HAS_WARP_FUNNEL_SHIFT__``
|
||||
- ``hasFunnelShift``
|
||||
- Funnel shift two input words into one
|
||||
*
|
||||
- ``__HIP_ARCH_HAS_THREAD_FENCE_SYSTEM__``
|
||||
- ``hasThreadFenceSystem``
|
||||
- :cpp:func:`threadfence_system`
|
||||
*
|
||||
- ``__HIP_ARCH_HAS_SYNC_THREAD_EXT__``
|
||||
- ``hasSyncThreadsExt``
|
||||
- :cpp:func:`syncthreads_count`, :cpp:func:`syncthreads_and`, :cpp:func:`syncthreads_or`
|
||||
*
|
||||
- ``__HIP_ARCH_HAS_SURFACE_FUNCS__``
|
||||
- ``hasSurfaceFuncs``
|
||||
- Supports :ref:`surface functions <surface_object_reference>`.
|
||||
*
|
||||
- ``__HIP_ARCH_HAS_3DGRID__``
|
||||
- ``has3dGrid``
|
||||
- Grids and groups are 3D
|
||||
*
|
||||
- ``__HIP_ARCH_HAS_DYNAMIC_PARALLEL__``
|
||||
- ``hasDynamicParallelism``
|
||||
- Ability to launch a kernel from within a kernel
|
||||
|
||||
Compilation
|
||||
================================================================================
|
||||
|
||||
``hipcc`` is a portable compiler driver that calls ``nvcc`` or ``amdclang++``
|
||||
and forwards the appropriate options. It passes options through
|
||||
to the target compiler. Tools that call ``hipcc`` must ensure the compiler
|
||||
options are appropriate for the target compiler.
|
||||
|
||||
``hipconfig`` is a helpful tool in identifying the current systems platform,
|
||||
compiler and runtime. It can also help set options appropriately.
|
||||
|
||||
As an example, it can provide a path to HIP, in Makefiles for example:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
HIP_PATH ?= $(shell hipconfig --path)
|
||||
|
||||
HIP Headers
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
The ``hip_runtime.h`` headers define all the necessary types, functions, macros,
|
||||
etc., needed to compile a HIP program, this includes host as well as device
|
||||
code. ``hip_runtime_api.h`` is a subset of ``hip_runtime.h``.
|
||||
|
||||
CUDA has slightly different contents for these two files. In some cases you may
|
||||
need to convert hipified code to include the richer ``hip_runtime.h`` instead of
|
||||
``hip_runtime_api.h``.
|
||||
|
||||
Using a Standard C++ Compiler
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
You can compile ``hip_runtime_api.h`` using a standard C or C++ compiler
|
||||
(e.g., ``gcc`` or ``icc``).
|
||||
A source file that is only calling HIP APIs but neither defines nor launches any
|
||||
kernels can be compiled with a standard host compiler (e.g. ``gcc`` or ``icc``)
|
||||
even when ``hip_runtime_api.h`` or ``hip_runtime.h`` are included.
|
||||
|
||||
The HIP include paths and platform macros (``__HIP_PLATFORM_AMD__`` or
|
||||
``__HIP_PLATFORM_NVIDIA__``) must be passed to the compiler.
|
||||
|
||||
``hipconfig`` can help in finding the necessary options, for example on an AMD
|
||||
platform:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
hipconfig --cpp_config
|
||||
-D__HIP_PLATFORM_AMD__= -I/opt/rocm/include
|
||||
|
||||
``nvcc`` includes some headers by default. ``hipcc`` does not include
|
||||
default headers, and instead all required files must be explicitly included.
|
||||
|
||||
The ``hipify`` tool automatically converts ``cuda_runtime.h`` to
|
||||
``hip_runtime.h``, and it converts ``cuda_runtime_api.h`` to
|
||||
``hip_runtime_api.h``, but it may miss nested headers or macros.
|
||||
|
||||
warpSize
|
||||
================================================================================
|
||||
|
||||
Code should not assume a warp size of 32 or 64, as that is not portable between
|
||||
platforms and architectures. The ``warpSize`` built-in should be used in device
|
||||
code, while the host can query it during runtime via the device properties. See
|
||||
the :ref:`HIP language extension for warpSize <warp_size>` for information on
|
||||
how to write portable wave-aware code.
|
||||
|
||||
Porting from CUDA __launch_bounds__
|
||||
================================================================================
|
||||
|
||||
CUDA also defines a ``__launch_bounds__`` qualifier which works similar to HIP's
|
||||
implementation, however it uses different parameters:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
__launch_bounds__(MAX_THREADS_PER_BLOCK, MIN_BLOCKS_PER_MULTIPROCESSOR)
|
||||
|
||||
The first parameter is the same as HIP's implementation, but
|
||||
``MIN_BLOCKS_PER_MULTIPROCESSOR`` must be converted to
|
||||
``MIN_WARPS_PER_EXECUTION``, which uses warps and execution units rather than
|
||||
blocks and multiprocessors. This conversion is performed automatically by
|
||||
:doc:`HIPIFY <hipify:index>`, or can be done manually with the following
|
||||
equation.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
MIN_WARPS_PER_EXECUTION_UNIT = (MIN_BLOCKS_PER_MULTIPROCESSOR * MAX_THREADS_PER_BLOCK) / warpSize
|
||||
|
||||
Directly controlling the warps per execution unit makes it easier to reason
|
||||
about the occupancy, unlike with blocks, where the occupancy depends on the
|
||||
block size.
|
||||
|
||||
The use of execution units rather than multiprocessors also provides support for
|
||||
architectures with multiple execution units per multiprocessor. For example, the
|
||||
AMD GCN architecture has 4 execution units per multiprocessor.
|
||||
|
||||
maxregcount
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Unlike ``nvcc``, ``amdclang++`` does not support the ``--maxregcount`` option.
|
||||
Instead, users are encouraged to use the ``__launch_bounds__`` directive since
|
||||
the parameters are more intuitive and portable than micro-architecture details
|
||||
like registers. The directive allows per-kernel control.
|
||||
@@ -0,0 +1,726 @@
|
||||
.. meta::
|
||||
:description: HIP runtime compiler (RTC)
|
||||
:keywords: AMD, ROCm, HIP, CUDA, RTC, HIP runtime compiler
|
||||
|
||||
.. _hip_runtime_compiler_how-to:
|
||||
|
||||
*******************************************************************************
|
||||
Programming for HIP runtime compiler (RTC)
|
||||
*******************************************************************************
|
||||
|
||||
HIP supports the kernels compilation at runtime with the ``hiprtc*`` APIs.
|
||||
Kernels can be stored as a text string and can be passed to HIPRTC APIs
|
||||
alongside options to guide the compilation.
|
||||
|
||||
.. note::
|
||||
|
||||
* This library can be used for compilation on systems without AMD GPU drivers
|
||||
installed (offline compilation). However, running the compiled code still
|
||||
requires both the HIP runtime library and GPU drivers on the target system.
|
||||
* This library depends on Code Object Manager (comgr). You can try to
|
||||
statically link comgr into HIPRTC to avoid ambiguity.
|
||||
* Developers can bundle this library with their application.
|
||||
|
||||
Compilation APIs
|
||||
===============================================================================
|
||||
|
||||
To use HIPRTC functionality the header needs to be included:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <hip/hiprtc.h>
|
||||
|
||||
Kernels can be stored in a string:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
static constexpr auto kernel_source {
|
||||
R"(
|
||||
extern "C"
|
||||
__global__ void vector_add(float* output, float* input1, float* input2, size_t size) {
|
||||
int i = threadIdx.x;
|
||||
if (i < size) {
|
||||
output[i] = input1[i] + input2[i];
|
||||
}
|
||||
}
|
||||
)"};
|
||||
|
||||
To compile this kernel, it needs to be associated with
|
||||
:cpp:struct:`hiprtcProgram` type, which is done by declaring :code:`hiprtcProgram prog;`
|
||||
and associating the string of kernel with this program:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
hiprtcCreateProgram(&prog, // HIPRTC program handle
|
||||
kernel_source, // HIP kernel source string
|
||||
"vector_add.cpp", // Name of the HIP program, can be null or an empty string
|
||||
0, // Number of headers
|
||||
NULL, // Header sources
|
||||
NULL); // Name of header files
|
||||
|
||||
:cpp:func:`hiprtcCreateProgram` API also allows you to add headers which can be
|
||||
included in your RTC program. For online compilation, the compiler pre-defines
|
||||
HIP device API functions, HIP specific types and macros for device compilation,
|
||||
but doesn't include standard C/C++ headers by default. Users can only include
|
||||
header files provided to :cpp:func:`hiprtcCreateProgram`.
|
||||
|
||||
After associating the kernel string with :cpp:struct:`hiprtcProgram`, you can
|
||||
now compile this program using:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
hiprtcCompileProgram(prog, // hiprtcProgram
|
||||
0, // Number of options
|
||||
options); // Clang Options [Supported Clang Options](clang_options.md)
|
||||
|
||||
:cpp:func:`hiprtcCompileProgram` returns a status value which can be converted
|
||||
to string via :cpp:func:`hiprtcGetErrorString`. If compilation is successful,
|
||||
:cpp:func:`hiprtcCompileProgram` will return ``HIPRTC_SUCCESS``.
|
||||
|
||||
if the compilation fails or produces warnings, you can look up the logs via:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
size_t logSize;
|
||||
hiprtcGetProgramLogSize(prog, &logSize);
|
||||
|
||||
if (logSize) {
|
||||
string log(logSize, '\0');
|
||||
hiprtcGetProgramLog(prog, &log[0]);
|
||||
// Corrective action with logs
|
||||
}
|
||||
|
||||
If the compilation is successful, you can load the compiled binary in a local
|
||||
variable.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
size_t codeSize;
|
||||
hiprtcGetCodeSize(prog, &codeSize);
|
||||
|
||||
vector<char> kernel_binary(codeSize);
|
||||
hiprtcGetCode(prog, kernel_binary.data());
|
||||
|
||||
After loading the binary, :cpp:struct:`hiprtcProgram` can be destroyed.
|
||||
:code:`hiprtcDestroyProgram(&prog);`
|
||||
|
||||
The binary present in ``kernel_binary`` can now be loaded via
|
||||
:cpp:func:`hipModuleLoadData` API.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
hipModule_t module;
|
||||
hipFunction_t kernel;
|
||||
|
||||
hipModuleLoadData(&module, kernel_binary.data());
|
||||
hipModuleGetFunction(&kernel, module, "vector_add");
|
||||
|
||||
And now this kernel can be launched via ``hipModule`` APIs.
|
||||
|
||||
The full example is below:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <hip/hiprtc.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#define CHECK_RET_CODE(call, ret_code) \
|
||||
{ \
|
||||
if ((call) != ret_code) { \
|
||||
std::cout << "Failed in call: " << #call << std::endl; \
|
||||
std::abort(); \
|
||||
} \
|
||||
}
|
||||
#define HIP_CHECK(call) CHECK_RET_CODE(call, hipSuccess)
|
||||
#define HIPRTC_CHECK(call) CHECK_RET_CODE(call, HIPRTC_SUCCESS)
|
||||
|
||||
// source code for hiprtc
|
||||
static constexpr auto kernel_source{
|
||||
R"(
|
||||
extern "C"
|
||||
__global__ void vector_add(float* output, float* input1, float* input2, size_t size) {
|
||||
int i = threadIdx.x;
|
||||
if (i < size) {
|
||||
output[i] = input1[i] + input2[i];
|
||||
}
|
||||
}
|
||||
)"};
|
||||
|
||||
int main() {
|
||||
hiprtcProgram prog;
|
||||
auto rtc_ret_code = hiprtcCreateProgram(&prog, // HIPRTC program handle
|
||||
kernel_source, // kernel source string
|
||||
"vector_add.cpp", // Name of the file
|
||||
0, // Number of headers
|
||||
NULL, // Header sources
|
||||
NULL); // Name of header file
|
||||
|
||||
if (rtc_ret_code != HIPRTC_SUCCESS) {
|
||||
std::cout << "Failed to create program" << std::endl;
|
||||
std::abort();
|
||||
}
|
||||
|
||||
hipDeviceProp_t props;
|
||||
int device = 0;
|
||||
HIP_CHECK(hipGetDeviceProperties(&props, device));
|
||||
std::string sarg = std::string("--gpu-architecture=") +
|
||||
props.gcnArchName; // device for which binary is to be generated
|
||||
|
||||
const char* options[] = {sarg.c_str()};
|
||||
|
||||
rtc_ret_code = hiprtcCompileProgram(prog, // hiprtcProgram
|
||||
0, // Number of options
|
||||
options); // Clang Options
|
||||
if (rtc_ret_code != HIPRTC_SUCCESS) {
|
||||
std::cout << "Failed to create program" << std::endl;
|
||||
std::abort();
|
||||
}
|
||||
|
||||
size_t logSize;
|
||||
HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize));
|
||||
|
||||
if (logSize) {
|
||||
std::string log(logSize, '\0');
|
||||
HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0]));
|
||||
std::cout << "Compilation failed or produced warnings: " << log << std::endl;
|
||||
std::abort();
|
||||
}
|
||||
|
||||
size_t codeSize;
|
||||
HIPRTC_CHECK(hiprtcGetCodeSize(prog, &codeSize));
|
||||
|
||||
std::vector<char> kernel_binary(codeSize);
|
||||
HIPRTC_CHECK(hiprtcGetCode(prog, kernel_binary.data()));
|
||||
|
||||
HIPRTC_CHECK(hiprtcDestroyProgram(&prog));
|
||||
|
||||
hipModule_t module;
|
||||
hipFunction_t kernel;
|
||||
|
||||
HIP_CHECK(hipModuleLoadData(&module, kernel_binary.data()));
|
||||
HIP_CHECK(hipModuleGetFunction(&kernel, module, "vector_add"));
|
||||
|
||||
constexpr size_t ele_size = 256; // total number of items to add
|
||||
std::vector<float> hinput, output;
|
||||
hinput.reserve(ele_size);
|
||||
output.reserve(ele_size);
|
||||
for (size_t i = 0; i < ele_size; i++) {
|
||||
hinput.push_back(static_cast<float>(i + 1));
|
||||
output.push_back(0.0f);
|
||||
}
|
||||
|
||||
float *dinput1, *dinput2, *doutput;
|
||||
HIP_CHECK(hipMalloc(&dinput1, sizeof(float) * ele_size));
|
||||
HIP_CHECK(hipMalloc(&dinput2, sizeof(float) * ele_size));
|
||||
HIP_CHECK(hipMalloc(&doutput, sizeof(float) * ele_size));
|
||||
|
||||
HIP_CHECK(hipMemcpy(dinput1, hinput.data(), sizeof(float) * ele_size, hipMemcpyHostToDevice));
|
||||
HIP_CHECK(hipMemcpy(dinput2, hinput.data(), sizeof(float) * ele_size, hipMemcpyHostToDevice));
|
||||
|
||||
struct {
|
||||
float* output;
|
||||
float* input1;
|
||||
float* input2;
|
||||
size_t size;
|
||||
} args{doutput, dinput1, dinput2, ele_size};
|
||||
|
||||
auto size = sizeof(args);
|
||||
void* config[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args, HIP_LAUNCH_PARAM_BUFFER_SIZE, &size,
|
||||
HIP_LAUNCH_PARAM_END};
|
||||
|
||||
HIP_CHECK(hipModuleLaunchKernel(kernel, 1, 1, 1, ele_size, 1, 1, 0, nullptr, nullptr, config));
|
||||
|
||||
HIP_CHECK(hipMemcpy(output.data(), doutput, sizeof(float) * ele_size, hipMemcpyDeviceToHost));
|
||||
|
||||
for (size_t i = 0; i < ele_size; i++) {
|
||||
if ((hinput[i] + hinput[i]) != output[i]) {
|
||||
std::cout << "Failed in validation: " << (hinput[i] + hinput[i]) << " - " << output[i]
|
||||
<< std::endl;
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
std::cout << "Passed" << std::endl;
|
||||
|
||||
HIP_CHECK(hipFree(dinput1));
|
||||
HIP_CHECK(hipFree(dinput2));
|
||||
HIP_CHECK(hipFree(doutput));
|
||||
}
|
||||
|
||||
|
||||
Kernel Compilation Cache
|
||||
===============================================================================
|
||||
|
||||
HIPRTC incorporates a cache to avoid recompiling kernels between program
|
||||
executions. The contents of the cache include the kernel source code (including
|
||||
the contents of any ``#include`` headers), the compilation flags, and the
|
||||
compiler version. After a ROCm version update, the kernels are progressively
|
||||
recompiled, and the new results are cached. When the cache is disabled, each
|
||||
kernel is recompiled every time it is requested.
|
||||
|
||||
Use the following environment variables to manage the cache status as enabled or
|
||||
disabled, the location for storing the cache contents, and the cache eviction
|
||||
policy:
|
||||
|
||||
* ``AMD_COMGR_CACHE`` By default this variable is unset and the
|
||||
compilation cache feature is enabled. To disable the feature set the
|
||||
environment variable to a value of ``0``.
|
||||
|
||||
* ``AMD_COMGR_CACHE_DIR``: By default the value of this environment variable is
|
||||
defined as ``$XDG_CACHE_HOME/comgr``, which defaults to
|
||||
``$USER/.cache/comgr`` on Linux, and ``%LOCALAPPDATA%\cache\comgr``
|
||||
on Windows. You can specify a different directory for the environment variable
|
||||
to change the path for cache storage. If the runtime fails to access the
|
||||
specified cache directory the cache is disabled. If the environment variable
|
||||
is set to an empty string (``""``), the default directory is used.
|
||||
|
||||
* ``AMD_COMGR_CACHE_POLICY``: If assigned a value, the string is interpreted and
|
||||
applied to the cache pruning policy. The string format is consistent with
|
||||
`Clang's ThinLTO cache pruning policy <https://rocm.docs.amd.com/projects/llvm-project/en/latest/LLVM/clang/html/ThinLTO.html#cache-pruning>`_.
|
||||
The default policy is defined as:
|
||||
``prune_interval=1h:prune_expiration=0h:cache_size=75%:cache_size_bytes=30g:cache_size_files=0``.
|
||||
If the runtime fails to parse the defined string, or the environment variable
|
||||
is set to an empty string (""), the cache is disabled.
|
||||
|
||||
.. note::
|
||||
|
||||
This cache is also shared with the OpenCL runtime shipped with ROCm.
|
||||
|
||||
HIPRTC specific options
|
||||
===============================================================================
|
||||
|
||||
HIPRTC provides a few HIPRTC specific flags:
|
||||
|
||||
* ``--gpu-architecture`` : This flag can guide the code object generation for a
|
||||
specific GPU architecture. Example:
|
||||
``--gpu-architecture=gfx906:sramecc+:xnack-``, its equivalent to
|
||||
``--offload-arch``.
|
||||
|
||||
* This option is compulsory if compilation is done on a system without AMD
|
||||
GPUs supported by HIP runtime.
|
||||
|
||||
* Otherwise, HIPRTC will load the hip runtime and gather the current device
|
||||
and its architecture info and use it as option.
|
||||
|
||||
* ``-fgpu-rdc`` : This flag when provided during the
|
||||
:cpp:func:`hiprtcCreateProgram` generates the bitcode (HIPRTC doesn't convert
|
||||
this bitcode into ISA and binary). This bitcode can later be fetched using
|
||||
:cpp:func:`hiprtcGetBitcode` and :cpp:func:`hiprtcGetBitcodeSize` APIs.
|
||||
|
||||
Bitcode
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
In the usual scenario, the kernel associated with :cpp:struct:`hiprtcProgram` is
|
||||
compiled into the binary which can be loaded and run. However, if ``-fgpu-rdc``
|
||||
option is provided in the compile options, HIPRTC calls comgr and generates only
|
||||
the LLVM bitcode. It doesn't convert this bitcode to ISA and generate the final
|
||||
binary.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
std::string sarg = std::string("-fgpu-rdc");
|
||||
const char* options[] = {
|
||||
sarg.c_str() };
|
||||
hiprtcCompileProgram(prog, // hiprtcProgram
|
||||
1, // Number of options
|
||||
options);
|
||||
|
||||
If the compilation is successful, one can load the bitcode in a local variable
|
||||
using the bitcode APIs provided by HIPRTC.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
size_t bitCodeSize;
|
||||
hiprtcGetBitcodeSize(prog, &bitCodeSize);
|
||||
|
||||
vector<char> kernel_bitcode(bitCodeSize);
|
||||
hiprtcGetBitcode(prog, kernel_bitcode.data());
|
||||
|
||||
CU Mode vs WGP mode
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
AMD GPUs consist of an array of workgroup processors, each built with 2 compute
|
||||
units (CUs) capable of executing SIMD32. All the CUs inside a workgroup
|
||||
processor use local data share (LDS).
|
||||
|
||||
gfx10+ support execution of wavefront in CU mode and work-group processor mode
|
||||
(WGP). Please refer to section 2.3 of `RDNA3 ISA reference <https://www.amd.com/content/dam/amd/en/documents/radeon-tech-docs/instruction-set-architectures/rdna3-shader-instruction-set-architecture-feb-2023_0.pdf>`_.
|
||||
|
||||
gfx9 and below only supports CU mode.
|
||||
|
||||
In WGP mode, 4 warps of a block can simultaneously be executed on the workgroup
|
||||
processor, where as in CU mode only 2 warps of a block can simultaneously
|
||||
execute on a CU. In theory, WGP mode might help with occupancy and increase the
|
||||
performance of certain HIP programs (if not bound to inter warp communication),
|
||||
but might incur performance penalty on other HIP programs which rely on atomics
|
||||
and inter warp communication. This also has effect of how the LDS is split
|
||||
between warps, please refer to `RDNA3 ISA reference <https://www.amd.com/content/dam/amd/en/documents/radeon-tech-docs/instruction-set-architectures/rdna3-shader-instruction-set-architecture-feb-2023_0.pdf>`_ for more information.
|
||||
|
||||
.. note::
|
||||
|
||||
HIPRTC assumes **WGP mode by default** for gfx10+. This can be overridden by
|
||||
passing ``-mcumode`` to HIPRTC compile options in
|
||||
:cpp:func:`hiprtcCompileProgram`.
|
||||
|
||||
Linker APIs
|
||||
===============================================================================
|
||||
|
||||
The bitcode generated using the HIPRTC Bitcode APIs can be loaded using
|
||||
``hipModule`` APIs and also can be linked with other generated bitcodes with
|
||||
appropriate linker flags using the HIPRTC linker APIs. This also provides more
|
||||
flexibility and optimizations to the applications who want to generate the
|
||||
binary dynamically according to their needs. The input bitcodes can be generated
|
||||
only for a specific architecture or it can be a bundled bitcode which is
|
||||
generated for multiple architectures.
|
||||
|
||||
Example
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Firstly, HIPRTC link instance or a pending linker invocation must be created
|
||||
using :cpp:func:`hiprtcLinkCreate`, with the appropriate linker options
|
||||
provided.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
hiprtcLinkCreate( num_options, // number of options
|
||||
options, // Array of options
|
||||
option_vals, // Array of option values cast to void*
|
||||
&rtc_link_state ); // HIPRTC link state created upon success
|
||||
|
||||
Following which, the bitcode data can be added to this link instance via
|
||||
:cpp:func:`hiprtcLinkAddData` (if the data is present as a string) or
|
||||
:cpp:func:`hiprtcLinkAddFile` (if the data is present as a file) with the
|
||||
appropriate input type according to the data or the bitcode used.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
hiprtcLinkAddData(rtc_link_state, // HIPRTC link state
|
||||
input_type, // type of the input data or bitcode
|
||||
bit_code_ptr, // input data which is null terminated
|
||||
bit_code_size, // size of the input data
|
||||
"a", // optional name for this input
|
||||
0, // size of the options
|
||||
0, // Array of options applied to this input
|
||||
0); // Array of option values cast to void*
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
hiprtcLinkAddFile(rtc_link_state, // HIPRTC link state
|
||||
input_type, // type of the input data or bitcode
|
||||
bc_file_path.c_str(), // path to the input file where bitcode is present
|
||||
0, // size of the options
|
||||
0, // Array of options applied to this input
|
||||
0); // Array of option values cast to void*
|
||||
|
||||
Once the bitcodes for multiple architectures are added to the link instance, the
|
||||
linking of the device code must be completed using :cpp:func:`hiprtcLinkComplete`
|
||||
which generates the final binary.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
hiprtcLinkComplete(rtc_link_state, // HIPRTC link state
|
||||
&binary, // upon success, points to the output binary
|
||||
&binarySize); // size of the binary is stored (optional)
|
||||
|
||||
If the :cpp:func:`hiprtcLinkComplete` returns successfully, the generated binary
|
||||
can be loaded and run using the ``hipModule*`` APIs.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
hipModuleLoadData(&module, binary);
|
||||
|
||||
.. note::
|
||||
|
||||
* The compiled binary must be loaded before HIPRTC link instance is destroyed
|
||||
using the :cpp:func:`hiprtcLinkDestroy` API.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
hiprtcLinkDestroy(rtc_link_state);
|
||||
|
||||
* The correct sequence of calls is : :cpp:func:`hiprtcLinkCreate`,
|
||||
:cpp:func:`hiprtcLinkAddData` or :cpp:func:`hiprtcLinkAddFile`,
|
||||
:cpp:func:`hiprtcLinkComplete`, :cpp:func:`hipModuleLoadData`,
|
||||
:cpp:func:`hiprtcLinkDestroy`.
|
||||
|
||||
Input Types
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
HIPRTC provides ``hiprtcJITInputType`` enumeration type which defines the input
|
||||
types accepted by the Linker APIs. Here are the ``enum`` values of
|
||||
``hiprtcJITInputType``. However only the input types
|
||||
``HIPRTC_JIT_INPUT_LLVM_BITCODE``, ``HIPRTC_JIT_INPUT_LLVM_BUNDLED_BITCODE`` and
|
||||
``HIPRTC_JIT_INPUT_LLVM_ARCHIVES_OF_BUNDLED_BITCODE`` are supported currently.
|
||||
|
||||
``HIPRTC_JIT_INPUT_LLVM_BITCODE`` can be used to load both LLVM bitcode or LLVM
|
||||
IR assembly code. However, ``HIPRTC_JIT_INPUT_LLVM_BUNDLED_BITCODE`` and
|
||||
``HIPRTC_JIT_INPUT_LLVM_ARCHIVES_OF_BUNDLED_BITCODE`` are only for bundled
|
||||
bitcode and archive of bundled bitcode.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
HIPRTC_JIT_INPUT_CUBIN = 0,
|
||||
HIPRTC_JIT_INPUT_PTX,
|
||||
HIPRTC_JIT_INPUT_FATBINARY,
|
||||
HIPRTC_JIT_INPUT_OBJECT,
|
||||
HIPRTC_JIT_INPUT_LIBRARY,
|
||||
HIPRTC_JIT_INPUT_NVVM,
|
||||
HIPRTC_JIT_NUM_LEGACY_INPUT_TYPES,
|
||||
HIPRTC_JIT_INPUT_LLVM_BITCODE = 100,
|
||||
HIPRTC_JIT_INPUT_LLVM_BUNDLED_BITCODE = 101,
|
||||
HIPRTC_JIT_INPUT_LLVM_ARCHIVES_OF_BUNDLED_BITCODE = 102,
|
||||
HIPRTC_JIT_NUM_INPUT_TYPES = (HIPRTC_JIT_NUM_LEGACY_INPUT_TYPES + 3)
|
||||
|
||||
Backward Compatibility of LLVM Bitcode/IR
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
For HIP applications utilizing HIPRTC to compile LLVM bitcode/IR, compatibility
|
||||
is assured only when the ROCm or HIP SDK version used for generating the LLVM
|
||||
bitcode/IR matches the version used during the runtime compilation. When an
|
||||
application requires the ingestion of bitcode/IR not derived from the currently
|
||||
installed AMD compiler, it must run with HIPRTC and comgr dynamic libraries that
|
||||
are compatible with the version of the bitcode/IR.
|
||||
|
||||
`Comgr <https://github.com/ROCm/llvm-project/tree/amd-staging/amd/comgr>`_ is a
|
||||
shared library that incorporates the LLVM/Clang compiler that HIPRTC relies on.
|
||||
To identify the bitcode/IR version that comgr is compatible with, one can
|
||||
execute "clang -v" using the clang binary from the same ROCm or HIP SDK package.
|
||||
For instance, if compiling bitcode/IR version 14, the HIPRTC and comgr libraries
|
||||
released by AMD around mid 2022 would be the best choice, assuming the
|
||||
LLVM/Clang version included in the package is also version 14.
|
||||
|
||||
To ensure smooth operation and compatibility, an application may choose to ship
|
||||
the specific versions of HIPRTC and comgr dynamic libraries, or it may opt to
|
||||
clearly specify the version requirements and dependencies. This approach
|
||||
guarantees that the application can correctly compile the specified version of
|
||||
bitcode/IR.
|
||||
|
||||
Link Options
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
* ``HIPRTC_JIT_IR_TO_ISA_OPT_EXT`` - AMD Only. Options to be passed on to link
|
||||
step of compiler by :cpp:func:`hiprtcLinkCreate`.
|
||||
|
||||
* ``HIPRTC_JIT_IR_TO_ISA_OPT_COUNT_EXT`` - AMD Only. Count of options passed on
|
||||
to link step of compiler.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
const char* isaopts[] = {"-mllvm", "-inline-threshold=1", "-mllvm", "-inlinehint-threshold=1"};
|
||||
std::vector<hiprtcJIT_option> jit_options = {HIPRTC_JIT_IR_TO_ISA_OPT_EXT,
|
||||
HIPRTC_JIT_IR_TO_ISA_OPT_COUNT_EXT};
|
||||
size_t isaoptssize = 4;
|
||||
const void* lopts[] = {(void*)isaopts, (void*)(isaoptssize)};
|
||||
hiprtcLinkState linkstate;
|
||||
hiprtcLinkCreate(2, jit_options.data(), (void**)lopts, &linkstate);
|
||||
|
||||
Error Handling
|
||||
===============================================================================
|
||||
|
||||
HIPRTC defines the ``hiprtcResult`` enumeration type and a function
|
||||
:cpp:func:`hiprtcGetErrorString` for API call error handling. ``hiprtcResult``
|
||||
``enum`` defines the API result codes. HIPRTC APIs return ``hiprtcResult`` to
|
||||
indicate the call result. :cpp:func:`hiprtcGetErrorString` function returns a
|
||||
string describing the given ``hiprtcResult`` code, for example HIPRTC_SUCCESS to
|
||||
"HIPRTC_SUCCESS". For unrecognized enumeration values, it returns
|
||||
"Invalid HIPRTC error code".
|
||||
|
||||
``hiprtcResult`` ``enum`` supported values and the
|
||||
:cpp:func:`hiprtcGetErrorString` usage are mentioned below.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
HIPRTC_SUCCESS = 0,
|
||||
HIPRTC_ERROR_OUT_OF_MEMORY = 1,
|
||||
HIPRTC_ERROR_PROGRAM_CREATION_FAILURE = 2,
|
||||
HIPRTC_ERROR_INVALID_INPUT = 3,
|
||||
HIPRTC_ERROR_INVALID_PROGRAM = 4,
|
||||
HIPRTC_ERROR_INVALID_OPTION = 5,
|
||||
HIPRTC_ERROR_COMPILATION = 6,
|
||||
HIPRTC_ERROR_LINKING = 7,
|
||||
HIPRTC_ERROR_BUILTIN_OPERATION_FAILURE = 8,
|
||||
HIPRTC_ERROR_NO_NAME_EXPRESSIONS_AFTER_COMPILATION = 9,
|
||||
HIPRTC_ERROR_NO_LOWERED_NAMES_BEFORE_COMPILATION = 10,
|
||||
HIPRTC_ERROR_NAME_EXPRESSION_NOT_VALID = 11,
|
||||
HIPRTC_ERROR_INTERNAL_ERROR = 12
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
hiprtcResult result;
|
||||
result = hiprtcCompileProgram(prog, 1, opts);
|
||||
if (result != HIPRTC_SUCCESS) {
|
||||
std::cout << "hiprtcCompileProgram fails with error " << hiprtcGetErrorString(result);
|
||||
}
|
||||
|
||||
HIPRTC General APIs
|
||||
===============================================================================
|
||||
|
||||
HIPRTC provides ``hiprtcVersion(int* major, int* minor)`` for querying the
|
||||
version. This sets the output parameters major and minor with the HIP Runtime
|
||||
compilation major version and minor version number respectively.
|
||||
|
||||
Currently, it returns hardcoded values. This should be implemented to return HIP
|
||||
runtime major and minor version in the future releases.
|
||||
|
||||
Lowered Names (Mangled Names)
|
||||
===============================================================================
|
||||
|
||||
HIPRTC mangles the ``__global__`` function names and names of ``__device__`` and
|
||||
``__constant__`` variables. If the generated binary is being loaded using the
|
||||
HIP Runtime API, the kernel function or ``__device__/__constant__`` variable
|
||||
must be looked up by name, but this is very hard when the name has been mangled.
|
||||
To overcome this, HIPRTC provides API functions that map ``__global__`` function
|
||||
or ``__device__/__constant__`` variable names in the source to the mangled names
|
||||
present in the generated binary.
|
||||
|
||||
The two APIs :cpp:func:`hiprtcAddNameExpression` and
|
||||
:cpp:func:`hiprtcGetLoweredName` provide this functionality. First, a 'name
|
||||
expression' string denoting the address for the ``__global__`` function or
|
||||
``__device__/__constant__`` variable is provided to
|
||||
:cpp:func:`hiprtcAddNameExpression`. Then, the program is compiled with
|
||||
:cpp:func:`hiprtcCreateProgram`. During compilation, HIPRTC will parse the name
|
||||
expression string as a C++ constant expression at the end of the user program.
|
||||
Finally, the function :cpp:func:`hiprtcGetLoweredName` is called with the
|
||||
original name expression and it returns a pointer to the lowered name. The
|
||||
lowered name can be used to refer to the kernel or variable in the HIP Runtime
|
||||
API.
|
||||
|
||||
.. note::
|
||||
|
||||
* The identical name expression string must be provided on a subsequent call
|
||||
to :cpp:func:`hiprtcGetLoweredName` to extract the lowered name.
|
||||
|
||||
* The correct sequence of calls is : :cpp:func:`hiprtcAddNameExpression`,
|
||||
:cpp:func:`hiprtcCreateProgram`, :cpp:func:`hiprtcGetLoweredName`,
|
||||
:cpp:func:`hiprtcDestroyProgram`.
|
||||
|
||||
* The lowered names must be fetched using :cpp:func:`hiprtcGetLoweredName`
|
||||
only after the HIPRTC program has been compiled, and before it has been
|
||||
destroyed.
|
||||
|
||||
Example
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Kernel containing various definitions ``__global__`` functions/function
|
||||
templates and ``__device__/__constant__`` variables can be stored in a string.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
static constexpr const char gpu_program[] {
|
||||
R"(
|
||||
__device__ int V1; // set from host code
|
||||
static __global__ void f1(int *result) { *result = V1 + 10; }
|
||||
namespace N1 {
|
||||
namespace N2 {
|
||||
__constant__ int V2; // set from host code
|
||||
__global__ void f2(int *result) { *result = V2 + 20; }
|
||||
}
|
||||
}
|
||||
template<typename T>
|
||||
__global__ void f3(int *result) { *result = sizeof(T); }
|
||||
)"};
|
||||
|
||||
:cpp:func:`hiprtcAddNameExpression` is called with various name expressions
|
||||
referring to the address of ``__global__`` functions and
|
||||
``__device__/__constant__`` variables.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
kernel_name_vec.push_back("&f1");
|
||||
kernel_name_vec.push_back("N1::N2::f2");
|
||||
kernel_name_vec.push_back("f3<int>");
|
||||
for (auto&& x : kernel_name_vec) hiprtcAddNameExpression(prog, x.c_str());
|
||||
variable_name_vec.push_back("&V1");
|
||||
variable_name_vec.push_back("&N1::N2::V2");
|
||||
for (auto&& x : variable_name_vec) hiprtcAddNameExpression(prog, x.c_str());
|
||||
|
||||
After which, the program is compiled using :cpp:func:`hiprtcCompileProgram`, the
|
||||
generated binary is loaded using :cpp:func:`hipModuleLoadData`, and the mangled
|
||||
names can be fetched using :cpp:func:`hirtcGetLoweredName`.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
for (decltype(variable_name_vec.size()) i = 0; i != variable_name_vec.size(); ++i) {
|
||||
const char* name;
|
||||
hiprtcGetLoweredName(prog, variable_name_vec[i].c_str(), &name);
|
||||
}
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
for (decltype(kernel_name_vec.size()) i = 0; i != kernel_name_vec.size(); ++i) {
|
||||
const char* name;
|
||||
hiprtcGetLoweredName(prog, kernel_name_vec[i].c_str(), &name);
|
||||
}
|
||||
|
||||
The mangled name of the variables are used to look up the variable in the module
|
||||
and update its value.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
hipDeviceptr_t variable_addr;
|
||||
size_t bytes{};
|
||||
hipModuleGetGlobal(&variable_addr, &bytes, module, name);
|
||||
hipMemcpyHtoD(variable_addr, &initial_value, sizeof(initial_value));
|
||||
|
||||
|
||||
Finally, the mangled name of the kernel is used to launch it using the
|
||||
``hipModule`` APIs.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
hipFunction_t kernel;
|
||||
hipModuleGetFunction(&kernel, module, name);
|
||||
hipModuleLaunchKernel(kernel, 1, 1, 1, 1, 1, 1, 0, nullptr, nullptr, config);
|
||||
|
||||
Versioning
|
||||
===============================================================================
|
||||
|
||||
HIPRTC uses the following versioning:
|
||||
|
||||
* Linux
|
||||
|
||||
* HIPRTC follows the same versioning as HIP runtime library.
|
||||
* The ``so`` name field for the shared library is set to MAJOR version. For
|
||||
example, for HIP 5.3 the ``so`` name is set to 5 (``hiprtc.so.5``).
|
||||
|
||||
* Windows
|
||||
|
||||
* HIPRTC dll is named as ``hiprtcXXYY.dll`` where ``XX`` is MAJOR version and
|
||||
``YY`` is MINOR version. For example, for HIP 5.3 the name is
|
||||
``hiprtc0503.dll``.
|
||||
|
||||
HIP header support
|
||||
===============================================================================
|
||||
|
||||
Added HIPRTC support for all the hip common header files such as
|
||||
``library_types.h``, ``hip_math_constants.h``, ``hip_complex.h``,
|
||||
``math_functions.h``, ``surface_types.h`` etc. from 6.1. HIPRTC users need not
|
||||
include any HIP macros or constants explicitly in their header files. All of
|
||||
these should get included via HIPRTC builtins when the app links to HIPRTC
|
||||
library.
|
||||
|
||||
Deprecation notice
|
||||
===============================================================================
|
||||
|
||||
* Currently HIPRTC APIs are separated from HIP APIs and HIPRTC is available as a
|
||||
separate library ``libhiprtc.so``/ ``libhiprtc.dll``. But on Linux, HIPRTC
|
||||
symbols are also present in ``libamdhip64.so`` in order to support the
|
||||
existing applications. Gradually, these symbols will be removed from HIP
|
||||
library and applications using HIPRTC will be required to explicitly link to
|
||||
HIPRTC library. However, on Windows ``hiprtc.dll`` must be used as the
|
||||
``amdhip64.dll`` doesn't contain the HIPRTC symbols.
|
||||
|
||||
* Data types such as ``uint32_t``, ``uint64_t``, ``int32_t``, ``int64_t``
|
||||
defined in std namespace in HIPRTC are deprecated earlier and are being
|
||||
removed from ROCm release 6.1 since these can conflict with the standard
|
||||
C++ data types. These data types are now prefixed with ``__hip__``, for example
|
||||
``__hip_uint32_t``. Applications previously using ``std::uint32_t`` or similar
|
||||
types can use ``__hip_`` prefixed types to avoid conflicts with standard std
|
||||
namespace or application can have their own definitions for these types. Also,
|
||||
type_traits templates previously defined in std namespace are moved to
|
||||
``__hip_internal`` namespace as implementation details.
|
||||
@@ -0,0 +1,49 @@
|
||||
.. meta::
|
||||
:description: HIP runtime API usage
|
||||
:keywords: AMD, ROCm, HIP, CUDA, HIP runtime API How to,
|
||||
|
||||
.. _hip_runtime_api_how-to:
|
||||
|
||||
********************************************************************************
|
||||
Using HIP runtime API
|
||||
********************************************************************************
|
||||
|
||||
The HIP runtime API provides C and C++ functionalities to manage event, stream,
|
||||
and memory on GPUs. On the AMD platform, the HIP runtime uses
|
||||
:doc:`Compute Language Runtime (CLR) <../understand/amd_clr>`, while on NVIDIA
|
||||
CUDA platform, it is only a thin layer over the CUDA runtime or Driver API.
|
||||
|
||||
- **CLR** contains source code for AMD's compute language runtimes: ``HIP`` and
|
||||
``OpenCL™``. CLR includes the ``HIP`` implementation on the AMD
|
||||
platform: `hipamd <https://github.com/ROCm/clr/tree/develop/hipamd>`_ and the
|
||||
ROCm Compute Language Runtime (``rocclr``). ``rocclr`` is a
|
||||
virtual device interface that enables the HIP runtime to interact with
|
||||
different backends such as :doc:`ROCr <rocr-runtime:index>` on Linux or PAL on
|
||||
Windows. CLR also includes the `OpenCL runtime <https://github.com/ROCm/clr/tree/develop/opencl>`_
|
||||
implementation.
|
||||
- The **CUDA runtime** is built on top of the CUDA driver API, which is a C API
|
||||
with lower-level access to NVIDIA GPUs. For details about the CUDA driver and
|
||||
runtime API with reference to HIP, see :doc:`CUDA driver API porting guide <../how-to/hip_porting_driver_api>`.
|
||||
|
||||
The backends of HIP runtime API under AMD and NVIDIA platform are summarized in
|
||||
the following figure:
|
||||
|
||||
.. figure:: ../data/how-to/hip_runtime_api/runtimes.svg
|
||||
|
||||
.. note::
|
||||
|
||||
On NVIDIA platform HIP runtime API calls CUDA runtime or CUDA driver via
|
||||
hipother interface. For more information, see the `hipother repository <https://github.com/ROCm/hipother>`_.
|
||||
|
||||
Here are the various HIP Runtime API high level functions:
|
||||
|
||||
* :doc:`./hip_runtime_api/initialization`
|
||||
* :doc:`./hip_runtime_api/memory_management`
|
||||
* :doc:`./hip_runtime_api/error_handling`
|
||||
* :doc:`./hip_runtime_api/asynchronous`
|
||||
* :doc:`./hip_runtime_api/cooperative_groups`
|
||||
* :doc:`./hip_runtime_api/hipgraph`
|
||||
* :doc:`./hip_runtime_api/call_stack`
|
||||
* :doc:`./hip_runtime_api/multi_device`
|
||||
* :doc:`./hip_runtime_api/opengl_interop`
|
||||
* :doc:`./hip_runtime_api/external_interop`
|
||||
@@ -0,0 +1,534 @@
|
||||
.. meta::
|
||||
:description: This topic describes asynchronous concurrent execution in HIP
|
||||
:keywords: AMD, ROCm, HIP, asynchronous concurrent execution, asynchronous, async, concurrent, concurrency
|
||||
|
||||
.. _asynchronous_how-to:
|
||||
|
||||
*******************************************************************************
|
||||
Asynchronous concurrent execution
|
||||
*******************************************************************************
|
||||
|
||||
Asynchronous concurrent execution is important for efficient parallelism and
|
||||
resource utilization, with techniques such as overlapping computation and data
|
||||
transfer, managing concurrent kernel execution with streams on single or
|
||||
multiple devices, or using HIP graphs.
|
||||
|
||||
Streams and concurrent execution
|
||||
===============================================================================
|
||||
|
||||
All asynchronous APIs, such as kernel execution, data movement and potentially
|
||||
data allocation/freeing all happen in the context of device streams.
|
||||
|
||||
Streams are FIFO buffers of commands to execute in order on a given device.
|
||||
Commands which enqueue tasks on a stream all return promptly and the task is
|
||||
executed asynchronously. Multiple streams can point to the same device and
|
||||
those streams might be fed from multiple concurrent host-side threads. Multiple
|
||||
streams tied to the same device are not guaranteed to execute their commands in
|
||||
order.
|
||||
|
||||
Managing streams
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Streams enable the overlap of computation and data transfer, ensuring
|
||||
continuous GPU activity. By enabling tasks to run concurrently within the same
|
||||
GPU or across different GPUs, streams improve performance and throughput in
|
||||
high-performance computing (HPC).
|
||||
|
||||
To create a stream, the following functions are used, each defining a handle
|
||||
to the newly created stream:
|
||||
|
||||
- :cpp:func:`hipStreamCreate`: Creates a stream with default settings.
|
||||
- :cpp:func:`hipStreamCreateWithFlags`: Creates a stream, with specific
|
||||
flags, listed below, enabling more control over stream behavior:
|
||||
|
||||
- ``hipStreamDefault``: creates a default stream suitable for most
|
||||
operations. The default stream is a blocking operation.
|
||||
- ``hipStreamNonBlocking``: creates a non-blocking stream, allowing
|
||||
concurrent execution of operations. It ensures that tasks can run
|
||||
simultaneously without waiting for each other to complete, thus improving
|
||||
overall performance.
|
||||
|
||||
- :cpp:func:`hipStreamCreateWithPriority`: Allows creating a stream with a
|
||||
specified priority, enabling prioritization of certain tasks.
|
||||
|
||||
The :cpp:func:`hipStreamSynchronize` function is used to block the calling host
|
||||
thread until all previously submitted tasks in a specified HIP stream have
|
||||
completed. It ensures that all operations in the given stream, such as kernel
|
||||
executions or memory transfers, are finished before the host thread proceeds.
|
||||
|
||||
.. note::
|
||||
|
||||
If the :cpp:func:`hipStreamSynchronize` function input stream is 0 (or the
|
||||
default stream), it waits for all operations in the default stream to
|
||||
complete.
|
||||
|
||||
Concurrent execution between host and device
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Concurrent execution between the host (CPU) and device (GPU) allows the CPU to
|
||||
perform other tasks while the GPU is executing kernels. Kernels are launched
|
||||
asynchronously using ``hipLaunchKernelGGL`` or using the triple chevron with a stream,
|
||||
enabling the CPU to continue executing other code while the GPU processes the
|
||||
kernel. Similarly, memory operations like :cpp:func:`hipMemcpyAsync` are
|
||||
performed asynchronously, allowing data transfers between the host and device
|
||||
without blocking the CPU.
|
||||
|
||||
Concurrent kernel execution
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Concurrent execution of multiple kernels on the GPU allows different kernels to
|
||||
run simultaneously to maximize GPU resource usage. Managing dependencies
|
||||
between kernels is crucial for ensuring correct execution order. This can be
|
||||
achieved using :cpp:func:`hipStreamWaitEvent`, which allows a kernel to wait
|
||||
for a specific event before starting execution.
|
||||
|
||||
Independent kernels can only run concurrently if there are enough registers
|
||||
and shared memory for the kernels. To enable concurrent kernel executions, the
|
||||
developer may have to reduce the block size of the kernels. The kernel runtimes
|
||||
can be misleading for concurrent kernel runs, that is why during optimization
|
||||
it is a good practice to check the trace files, to see if one kernel is blocking
|
||||
another kernel, while they are running in parallel. For more information about
|
||||
the application tracing, check::doc:`rocprofiler:/how-to/using-rocprof`.
|
||||
|
||||
When running kernels in parallel, the execution time can increase due to
|
||||
contention for shared resources. This is because multiple kernels may attempt
|
||||
to access the same GPU resources simultaneously, leading to delays.
|
||||
|
||||
Multiple kernels executing concurrently is only beneficial under specific conditions. It
|
||||
is most effective when the kernels do not fully utilize the GPU's resources. In
|
||||
such cases, overlapping kernel execution can improve overall throughput and
|
||||
efficiency by keeping the GPU busy without exceeding its capacity.
|
||||
|
||||
Overlap of data transfer and kernel execution
|
||||
===============================================================================
|
||||
|
||||
One of the primary benefits of asynchronous operations and multiple streams is
|
||||
the ability to overlap data transfer with kernel execution, leading to better
|
||||
resource utilization and improved performance.
|
||||
|
||||
Asynchronous execution is particularly advantageous in iterative processes. For
|
||||
instance, if a kernel is initiated, it can be efficient to prepare the input
|
||||
data simultaneously, provided that this preparation does not depend on the
|
||||
kernel's execution. Such iterative data transfer and kernel execution overlap
|
||||
can be find in the :ref:`async_example`.
|
||||
|
||||
Querying device capabilities
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Some AMD HIP-enabled devices can perform asynchronous memory copy operations to
|
||||
or from the GPU concurrently with kernel execution. Applications can query this
|
||||
capability by checking the ``asyncEngineCount`` device property. Devices with
|
||||
an ``asyncEngineCount`` greater than zero support concurrent data transfers.
|
||||
Additionally, if host memory is involved in the copy, it should be page-locked
|
||||
to ensure optimal performance. Page-locking (or pinning) host memory increases
|
||||
the bandwidth between the host and the device, reducing the overhead associated
|
||||
with data transfers. For more details, visit :ref:`host_memory` page.
|
||||
|
||||
Asynchronous memory operations
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Asynchronous memory operations do not block the host while copying data and,
|
||||
when used with multiple streams, allow data to be transferred between the host
|
||||
and device while kernels are executed on the same GPU. Using operations like
|
||||
:cpp:func:`hipMemcpyAsync` or :cpp:func:`hipMemcpyPeerAsync`, developers can
|
||||
initiate data transfers without waiting for the previous operation to complete.
|
||||
This overlap of computation and data transfer ensures that the GPU is not idle
|
||||
while waiting for data. :cpp:func:`hipMemcpyPeerAsync` enables data transfers
|
||||
between different GPUs, facilitating multi-GPU communication.
|
||||
|
||||
:ref:`async_example` include launching kernels in one stream while performing
|
||||
data transfers in another. This technique is especially useful in applications
|
||||
with large data sets that need to be processed quickly.
|
||||
|
||||
Concurrent data transfers with intra-device copies
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Devices that support the ``concurrentKernels`` property can perform
|
||||
intra-device copies concurrently with kernel execution. Additionally, devices
|
||||
that support the ``asyncEngineCount`` property can perform data transfers to
|
||||
or from the GPU simultaneously with kernel execution. Intra-device copies can
|
||||
be initiated using standard memory copy functions with destination and source
|
||||
addresses residing on the same device.
|
||||
|
||||
Synchronization, event management and synchronous calls
|
||||
===============================================================================
|
||||
|
||||
Synchronization and event management are important for coordinating tasks and
|
||||
ensuring correct execution order, and synchronous calls are necessary for
|
||||
maintaining data consistency.
|
||||
|
||||
Synchronous calls
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Synchronous calls ensure task completion before moving to the next operation.
|
||||
For example, :cpp:func:`hipMemcpy` for data transfers waits for completion
|
||||
before returning control to the host. Similarly, synchronous kernel launches
|
||||
are used when immediate completion is required. When a synchronous function is
|
||||
called, control is not returned to the host thread before the device has
|
||||
completed the requested task. The behavior of the host thread—whether to yield,
|
||||
block, or spin—can be specified using :cpp:func:`hipSetDeviceFlags` with
|
||||
appropriate flags. Understanding when to use synchronous calls is important for
|
||||
managing execution flow and avoiding data races.
|
||||
|
||||
Events for synchronization
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
By creating an event with :cpp:func:`hipEventCreate` and recording it with
|
||||
:cpp:func:`hipEventRecord`, developers can synchronize operations across
|
||||
streams, ensuring correct task execution order. :cpp:func:`hipEventSynchronize`
|
||||
lets the application wait for an event to complete before proceeding with the next
|
||||
operation.
|
||||
|
||||
Programmatic dependent launch and synchronization
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
While CUDA supports programmatic dependent launches allowing a secondary kernel
|
||||
to start before the primary kernel finishes, HIP achieves similar functionality
|
||||
using streams and events. By employing :cpp:func:`hipStreamWaitEvent`, it is
|
||||
possible to manage the execution order without explicit hardware support. This
|
||||
mechanism allows a secondary kernel to launch as soon as the necessary
|
||||
conditions are met, even if the primary kernel is still running.
|
||||
|
||||
.. _async_example:
|
||||
|
||||
Example
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
The examples shows the difference between sequential, asynchronous calls and
|
||||
asynchronous calls with ``hipEvents``.
|
||||
|
||||
.. figure:: ../../data/how-to/hip_runtime_api/asynchronous/sequential_async_event.svg
|
||||
:alt: Compare the different calls
|
||||
:align: center
|
||||
|
||||
The example codes
|
||||
|
||||
.. tab-set::
|
||||
|
||||
.. tab-item:: Sequential
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
#define HIP_CHECK(expression) \
|
||||
{ \
|
||||
const hipError_t status = expression; \
|
||||
if(status != hipSuccess){ \
|
||||
std::cerr << "HIP error " \
|
||||
<< status << ": " \
|
||||
<< hipGetErrorString(status) \
|
||||
<< " at " << __FILE__ << ":" \
|
||||
<< __LINE__ << std::endl; \
|
||||
} \
|
||||
}
|
||||
|
||||
// GPU Kernels
|
||||
__global__ void kernelA(double* arrayA, size_t size){
|
||||
const size_t x = threadIdx.x + blockDim.x * blockIdx.x;
|
||||
if(x < size){arrayA[x] += 1.0;}
|
||||
};
|
||||
__global__ void kernelB(double* arrayA, double* arrayB, size_t size){
|
||||
const size_t x = threadIdx.x + blockDim.x * blockIdx.x;
|
||||
if(x < size){arrayB[x] += arrayA[x] + 3.0;}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
constexpr int numOfBlocks = 1 << 20;
|
||||
constexpr int threadsPerBlock = 1024;
|
||||
constexpr int numberOfIterations = 50;
|
||||
// The array size smaller to avoid the relatively short kernel launch compared to memory copies
|
||||
constexpr size_t arraySize = 1U << 25;
|
||||
double *d_dataA;
|
||||
double *d_dataB;
|
||||
|
||||
double initValueA = 0.0;
|
||||
double initValueB = 2.0;
|
||||
|
||||
std::vector<double> vectorA(arraySize, initValueA);
|
||||
std::vector<double> vectorB(arraySize, initValueB);
|
||||
// Allocate device memory
|
||||
HIP_CHECK(hipMalloc(&d_dataA, arraySize * sizeof(*d_dataA)));
|
||||
HIP_CHECK(hipMalloc(&d_dataB, arraySize * sizeof(*d_dataB)));
|
||||
for(int iteration = 0; iteration < numberOfIterations; iteration++)
|
||||
{
|
||||
// Host to Device copies
|
||||
HIP_CHECK(hipMemcpy(d_dataA, vectorA.data(), arraySize * sizeof(*d_dataA), hipMemcpyHostToDevice));
|
||||
HIP_CHECK(hipMemcpy(d_dataB, vectorB.data(), arraySize * sizeof(*d_dataB), hipMemcpyHostToDevice));
|
||||
// Launch the GPU kernels
|
||||
hipLaunchKernelGGL(kernelA, dim3(numOfBlocks), dim3(threadsPerBlock), 0, 0, d_dataA, arraySize);
|
||||
hipLaunchKernelGGL(kernelB, dim3(numOfBlocks), dim3(threadsPerBlock), 0, 0, d_dataA, d_dataB, arraySize);
|
||||
// Device to Host copies
|
||||
HIP_CHECK(hipMemcpy(vectorA.data(), d_dataA, arraySize * sizeof(*vectorA.data()), hipMemcpyDeviceToHost));
|
||||
HIP_CHECK(hipMemcpy(vectorB.data(), d_dataB, arraySize * sizeof(*vectorB.data()), hipMemcpyDeviceToHost));
|
||||
}
|
||||
// Wait for all operations to complete
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
|
||||
// Verify results
|
||||
const double expectedA = (double)numberOfIterations;
|
||||
const double expectedB =
|
||||
initValueB + (3.0 * numberOfIterations) +
|
||||
(expectedA * (expectedA + 1.0)) / 2.0;
|
||||
bool passed = true;
|
||||
for(size_t i = 0; i < arraySize; ++i){
|
||||
if(vectorA[i] != expectedA){
|
||||
passed = false;
|
||||
std::cerr << "Validation failed! Expected " << expectedA << " got " << vectorA[i] << " at index: " << i << std::endl;
|
||||
break;
|
||||
}
|
||||
if(vectorB[i] != expectedB){
|
||||
passed = false;
|
||||
std::cerr << "Validation failed! Expected " << expectedB << " got " << vectorB[i] << " at index: " << i << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(passed){
|
||||
std::cout << "Sequential execution completed successfully." << std::endl;
|
||||
}else{
|
||||
std::cerr << "Sequential execution failed." << std::endl;
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
HIP_CHECK(hipFree(d_dataA));
|
||||
HIP_CHECK(hipFree(d_dataB));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
.. tab-item:: Asynchronous
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
#define HIP_CHECK(expression) \
|
||||
{ \
|
||||
const hipError_t status = expression; \
|
||||
if(status != hipSuccess){ \
|
||||
std::cerr << "HIP error " \
|
||||
<< status << ": " \
|
||||
<< hipGetErrorString(status) \
|
||||
<< " at " << __FILE__ << ":" \
|
||||
<< __LINE__ << std::endl; \
|
||||
} \
|
||||
}
|
||||
|
||||
// GPU Kernels
|
||||
__global__ void kernelA(double* arrayA, size_t size){
|
||||
const size_t x = threadIdx.x + blockDim.x * blockIdx.x;
|
||||
if(x < size){arrayA[x] += 1.0;}
|
||||
};
|
||||
__global__ void kernelB(double* arrayA, double* arrayB, size_t size){
|
||||
const size_t x = threadIdx.x + blockDim.x * blockIdx.x;
|
||||
if(x < size){arrayB[x] += arrayA[x] + 3.0;}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
constexpr int numOfBlocks = 1 << 20;
|
||||
constexpr int threadsPerBlock = 1024;
|
||||
constexpr int numberOfIterations = 50;
|
||||
// The array size smaller to avoid the relatively short kernel launch compared to memory copies
|
||||
constexpr size_t arraySize = 1U << 25;
|
||||
double *d_dataA;
|
||||
double *d_dataB;
|
||||
|
||||
double initValueA = 0.0;
|
||||
double initValueB = 2.0;
|
||||
|
||||
std::vector<double> vectorA(arraySize, initValueA);
|
||||
std::vector<double> vectorB(arraySize, initValueB);
|
||||
// Allocate device memory
|
||||
HIP_CHECK(hipMalloc(&d_dataA, arraySize * sizeof(*d_dataA)));
|
||||
HIP_CHECK(hipMalloc(&d_dataB, arraySize * sizeof(*d_dataB)));
|
||||
// Create streams
|
||||
hipStream_t streamA, streamB;
|
||||
HIP_CHECK(hipStreamCreate(&streamA));
|
||||
HIP_CHECK(hipStreamCreate(&streamB));
|
||||
for(unsigned int iteration = 0; iteration < numberOfIterations; iteration++)
|
||||
{
|
||||
// Stream 1: Host to Device 1
|
||||
HIP_CHECK(hipMemcpyAsync(d_dataA, vectorA.data(), arraySize * sizeof(*d_dataA), hipMemcpyHostToDevice, streamA));
|
||||
// Stream 2: Host to Device 2
|
||||
HIP_CHECK(hipMemcpyAsync(d_dataB, vectorB.data(), arraySize * sizeof(*d_dataB), hipMemcpyHostToDevice, streamB));
|
||||
// Stream 1: Kernel 1
|
||||
hipLaunchKernelGGL(kernelA, dim3(numOfBlocks), dim3(threadsPerBlock), 0, streamA, d_dataA, arraySize);
|
||||
// Wait for streamA finish
|
||||
HIP_CHECK(hipStreamSynchronize(streamA));
|
||||
// Stream 2: Kernel 2
|
||||
hipLaunchKernelGGL(kernelB, dim3(numOfBlocks), dim3(threadsPerBlock), 0, streamB, d_dataA, d_dataB, arraySize);
|
||||
// Stream 1: Device to Host 2 (after Kernel 1)
|
||||
HIP_CHECK(hipMemcpyAsync(vectorA.data(), d_dataA, arraySize * sizeof(*vectorA.data()), hipMemcpyDeviceToHost, streamA));
|
||||
// Stream 2: Device to Host 2 (after Kernel 2)
|
||||
HIP_CHECK(hipMemcpyAsync(vectorB.data(), d_dataB, arraySize * sizeof(*vectorB.data()), hipMemcpyDeviceToHost, streamB));
|
||||
}
|
||||
// Wait for all operations in both streams to complete
|
||||
HIP_CHECK(hipStreamSynchronize(streamA));
|
||||
HIP_CHECK(hipStreamSynchronize(streamB));
|
||||
// Verify results
|
||||
double expectedA = (double)numberOfIterations;
|
||||
double expectedB =
|
||||
initValueB + (3.0 * numberOfIterations) +
|
||||
(expectedA * (expectedA + 1.0)) / 2.0;
|
||||
bool passed = true;
|
||||
for(size_t i = 0; i < arraySize; ++i){
|
||||
if(vectorA[i] != expectedA){
|
||||
passed = false;
|
||||
std::cerr << "Validation failed! Expected " << expectedA << " got " << vectorA[i] << " at index: " << i << std::endl;
|
||||
break;
|
||||
}
|
||||
if(vectorB[i] != expectedB){
|
||||
passed = false;
|
||||
std::cerr << "Validation failed! Expected " << expectedB << " got " << vectorB[i] << " at index: " << i << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(passed){
|
||||
std::cout << "Asynchronous execution completed successfully." << std::endl;
|
||||
}else{
|
||||
std::cerr << "Asynchronous execution failed." << std::endl;
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
HIP_CHECK(hipStreamDestroy(streamA));
|
||||
HIP_CHECK(hipStreamDestroy(streamB));
|
||||
HIP_CHECK(hipFree(d_dataA));
|
||||
HIP_CHECK(hipFree(d_dataB));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
.. tab-item:: hipStreamWaitEvent
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
#define HIP_CHECK(expression) \
|
||||
{ \
|
||||
const hipError_t status = expression; \
|
||||
if(status != hipSuccess){ \
|
||||
std::cerr << "HIP error " \
|
||||
<< status << ": " \
|
||||
<< hipGetErrorString(status) \
|
||||
<< " at " << __FILE__ << ":" \
|
||||
<< __LINE__ << std::endl; \
|
||||
} \
|
||||
}
|
||||
|
||||
// GPU Kernels
|
||||
__global__ void kernelA(double* arrayA, size_t size){
|
||||
const size_t x = threadIdx.x + blockDim.x * blockIdx.x;
|
||||
if(x < size){arrayA[x] += 1.0;}
|
||||
};
|
||||
__global__ void kernelB(double* arrayA, double* arrayB, size_t size){
|
||||
const size_t x = threadIdx.x + blockDim.x * blockIdx.x;
|
||||
if(x < size){arrayB[x] += arrayA[x] + 3.0;}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
constexpr int numOfBlocks = 1 << 20;
|
||||
constexpr int threadsPerBlock = 1024;
|
||||
constexpr int numberOfIterations = 50;
|
||||
// The array size smaller to avoid the relatively short kernel launch compared to memory copies
|
||||
constexpr size_t arraySize = 1U << 25;
|
||||
double *d_dataA;
|
||||
double *d_dataB;
|
||||
double initValueA = 0.0;
|
||||
double initValueB = 2.0;
|
||||
|
||||
std::vector<double> vectorA(arraySize, initValueA);
|
||||
std::vector<double> vectorB(arraySize, initValueB);
|
||||
// Allocate device memory
|
||||
HIP_CHECK(hipMalloc(&d_dataA, arraySize * sizeof(*d_dataA)));
|
||||
HIP_CHECK(hipMalloc(&d_dataB, arraySize * sizeof(*d_dataB)));
|
||||
// Create streams
|
||||
hipStream_t streamA, streamB;
|
||||
HIP_CHECK(hipStreamCreate(&streamA));
|
||||
HIP_CHECK(hipStreamCreate(&streamB));
|
||||
// Create events
|
||||
hipEvent_t event, eventA, eventB;
|
||||
HIP_CHECK(hipEventCreate(&event));
|
||||
HIP_CHECK(hipEventCreate(&eventA));
|
||||
HIP_CHECK(hipEventCreate(&eventB));
|
||||
for(unsigned int iteration = 0; iteration < numberOfIterations; iteration++)
|
||||
{
|
||||
// Stream 1: Host to Device 1
|
||||
HIP_CHECK(hipMemcpyAsync(d_dataA, vectorA.data(), arraySize * sizeof(*d_dataA), hipMemcpyHostToDevice, streamA));
|
||||
// Stream 2: Host to Device 2
|
||||
HIP_CHECK(hipMemcpyAsync(d_dataB, vectorB.data(), arraySize * sizeof(*d_dataB), hipMemcpyHostToDevice, streamB));
|
||||
// Stream 1: Kernel 1
|
||||
hipLaunchKernelGGL(kernelA, dim3(numOfBlocks), dim3(threadsPerBlock), 0, streamA, d_dataA, arraySize);
|
||||
// Record event after the GPU kernel in Stream 1
|
||||
HIP_CHECK(hipEventRecord(event, streamA));
|
||||
// Stream 2: Wait for event before starting Kernel 2
|
||||
HIP_CHECK(hipStreamWaitEvent(streamB, event, 0));
|
||||
// Stream 2: Kernel 2
|
||||
hipLaunchKernelGGL(kernelB, dim3(numOfBlocks), dim3(threadsPerBlock), 0, streamB, d_dataA, d_dataB, arraySize);
|
||||
// Stream 1: Device to Host 2 (after Kernel 1)
|
||||
HIP_CHECK(hipMemcpyAsync(vectorA.data(), d_dataA, arraySize * sizeof(*vectorA.data()), hipMemcpyDeviceToHost, streamA));
|
||||
// Stream 2: Device to Host 2 (after Kernel 2)
|
||||
HIP_CHECK(hipMemcpyAsync(vectorB.data(), d_dataB, arraySize * sizeof(*vectorB.data()), hipMemcpyDeviceToHost, streamB));
|
||||
// Wait for all operations in both streams to complete
|
||||
HIP_CHECK(hipEventRecord(eventA, streamA));
|
||||
HIP_CHECK(hipEventRecord(eventB, streamB));
|
||||
HIP_CHECK(hipStreamWaitEvent(streamA, eventA, 0));
|
||||
HIP_CHECK(hipStreamWaitEvent(streamB, eventB, 0));
|
||||
}
|
||||
// Verify results
|
||||
double expectedA = (double)numberOfIterations;
|
||||
double expectedB =
|
||||
initValueB + (3.0 * numberOfIterations) +
|
||||
(expectedA * (expectedA + 1.0)) / 2.0;
|
||||
bool passed = true;
|
||||
for(size_t i = 0; i < arraySize; ++i){
|
||||
if(vectorA[i] != expectedA){
|
||||
passed = false;
|
||||
std::cerr << "Validation failed! Expected " << expectedA << " got " << vectorA[i] << std::endl;
|
||||
break;
|
||||
}
|
||||
if(vectorB[i] != expectedB){
|
||||
passed = false;
|
||||
std::cerr << "Validation failed! Expected " << expectedB << " got " << vectorB[i] << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(passed){
|
||||
std::cout << "Asynchronous execution with events completed successfully." << std::endl;
|
||||
}else{
|
||||
std::cerr << "Asynchronous execution with events failed." << std::endl;
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
HIP_CHECK(hipEventDestroy(event));
|
||||
HIP_CHECK(hipEventDestroy(eventA));
|
||||
HIP_CHECK(hipEventDestroy(eventB));
|
||||
HIP_CHECK(hipStreamDestroy(streamA));
|
||||
HIP_CHECK(hipStreamDestroy(streamB));
|
||||
HIP_CHECK(hipFree(d_dataA));
|
||||
HIP_CHECK(hipFree(d_dataB));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
HIP Graphs
|
||||
===============================================================================
|
||||
|
||||
HIP graphs offer an efficient alternative to the standard method of launching
|
||||
GPU tasks via streams. Comprising nodes for operations and edges for
|
||||
dependencies, HIP graphs reduce kernel launch overhead and provide a high-level
|
||||
abstraction for managing dependencies and synchronization. By representing
|
||||
sequences of kernels and memory operations as a single graph, they simplify
|
||||
complex workflows and enhance performance, particularly for applications with
|
||||
intricate dependencies and multiple execution stages.
|
||||
For more details, see the :ref:`how_to_HIP_graph` documentation.
|
||||
@@ -0,0 +1,129 @@
|
||||
.. meta::
|
||||
:description: This page describes call stack concept in HIP
|
||||
:keywords: AMD, ROCm, HIP, call stack
|
||||
|
||||
*******************************************************************************
|
||||
Call stack
|
||||
*******************************************************************************
|
||||
|
||||
The call stack is a data structure for managing function calls, by saving the
|
||||
state of the current function. Each time a function is called, a new call frame
|
||||
is added to the top of the stack, containing information such as local
|
||||
variables, return addresses and function parameters. When the function
|
||||
execution completes, the frame is removed from the stack and loaded back into
|
||||
the corresponding registers. This concept allows the program to return to the
|
||||
calling function and continue execution from where it left off.
|
||||
|
||||
The call stack for each thread must track its function calls, local variables,
|
||||
and return addresses. However, in GPU programming, the memory required to store
|
||||
the call stack increases due to the parallelism inherent to the GPUs. NVIDIA
|
||||
and AMD GPUs use different approaches. NVIDIA GPUs have the independent thread
|
||||
scheduling feature where each thread has its own call stack and effective
|
||||
program counter. On AMD GPUs threads are grouped; each warp has its own call
|
||||
stack and program counter. Warps are described and explained in the
|
||||
:ref:`inherent_thread_hierarchy`
|
||||
|
||||
If a thread or warp exceeds its stack size, a stack overflow occurs, causing
|
||||
kernel failure. This can be detected using debuggers.
|
||||
|
||||
Call stack management with HIP
|
||||
===============================================================================
|
||||
|
||||
You can adjust the call stack size as shown in the following example, allowing
|
||||
fine-tuning based on specific kernel requirements. This helps prevent stack
|
||||
overflow errors by ensuring sufficient stack memory is allocated.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <iostream>
|
||||
|
||||
#define HIP_CHECK(expression) \
|
||||
{ \
|
||||
const hipError_t status = expression; \
|
||||
if(status != hipSuccess){ \
|
||||
std::cerr << "HIP error " \
|
||||
<< status << ": " \
|
||||
<< hipGetErrorString(status) \
|
||||
<< " at " << __FILE__ << ":" \
|
||||
<< __LINE__ << std::endl; \
|
||||
} \
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
size_t stackSize;
|
||||
HIP_CHECK(hipDeviceGetLimit(&stackSize, hipLimitStackSize));
|
||||
std::cout << "Default stack size: " << stackSize << " bytes" << std::endl;
|
||||
|
||||
// Set a new stack size
|
||||
size_t newStackSize = 1024 * 8; // 8 KiB
|
||||
HIP_CHECK(hipDeviceSetLimit(hipLimitStackSize, newStackSize));
|
||||
|
||||
HIP_CHECK(hipDeviceGetLimit(&stackSize, hipLimitStackSize));
|
||||
std::cout << "Updated stack size: " << stackSize << " bytes" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Depending on the GPU model, at full occupancy, it can consume a significant
|
||||
amount of memory. For instance, an MI300X with 304 compute units (CU) and up to
|
||||
2048 threads per CU could use 304 · 2048 · 1024 bytes = 608 MiB for the call
|
||||
stack by default.
|
||||
|
||||
Handling recursion and deep function calls
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Similar to CPU programming, recursive functions and deeply nested function
|
||||
calls are supported. However, developers must ensure that these functions do
|
||||
not exceed the available stack memory, considering the huge amount of memory
|
||||
needed for the call stack due to the GPUs inherent parallelism. This can be
|
||||
achieved by increasing stack size or optimizing code to reduce stack usage. To
|
||||
detect stack overflow add proper error handling or use debugging tools.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <iostream>
|
||||
|
||||
#define HIP_CHECK(expression) \
|
||||
{ \
|
||||
const hipError_t status = expression; \
|
||||
if(status != hipSuccess){ \
|
||||
std::cerr << "HIP error " \
|
||||
<< status << ": " \
|
||||
<< hipGetErrorString(status) \
|
||||
<< " at " << __FILE__ << ":" \
|
||||
<< __LINE__ << std::endl; \
|
||||
} \
|
||||
}
|
||||
|
||||
__device__ unsigned long long fibonacci(unsigned long long n)
|
||||
{
|
||||
if (n == 0 || n == 1)
|
||||
{
|
||||
return n;
|
||||
}
|
||||
return fibonacci(n - 1) + fibonacci(n - 2);
|
||||
}
|
||||
|
||||
__global__ void kernel(unsigned long long n)
|
||||
{
|
||||
unsigned long long result = fibonacci(n);
|
||||
const size_t x = threadIdx.x + blockDim.x * blockIdx.x;
|
||||
|
||||
if (x == 0)
|
||||
printf("%llu! = %llu \n", n, result);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
kernel<<<1, 1>>>(10);
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
|
||||
// With -O0 optimization option hit the stack limit
|
||||
// kernel<<<1, 256>>>(2048);
|
||||
// HIP_CHECK(hipDeviceSynchronize());
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,502 @@
|
||||
.. meta::
|
||||
:description: This topic describes how to use cooperative groups in HIP
|
||||
:keywords: AMD, ROCm, HIP, cooperative groups
|
||||
|
||||
.. _cooperative_groups_how-to:
|
||||
|
||||
*******************************************************************************
|
||||
Cooperative groups
|
||||
*******************************************************************************
|
||||
|
||||
The cooperative groups API is an extension to the HIP programming model, which
|
||||
provides developers with a flexible, dynamic grouping mechanism for the
|
||||
communicating threads. Cooperative groups let you define your own set of thread
|
||||
groups which may fit your use-cases better than those defined by the hardware.
|
||||
This lets you specify the level of granularity for thread communication which
|
||||
can lead to more efficient parallel decompositions.
|
||||
|
||||
The API is accessible in the ``cooperative_groups`` namespace after the
|
||||
``hip_cooperative_groups.h`` header is included. The header contains the following
|
||||
elements:
|
||||
|
||||
* Static functions to create groups and subgroups.
|
||||
* Hardware-accelerated operations over the whole group, like shuffles.
|
||||
* Data types of cooperative groups.
|
||||
* Synchronize member function of the groups.
|
||||
* Get group properties member functions.
|
||||
|
||||
Cooperative groups thread model
|
||||
================================================================================
|
||||
|
||||
The thread hierarchy abstractions of cooperative groups are depicted in the following figures: :ref:`grid hierarchy <coop_thread_top_hierarchy>` and :ref:`block hierarchy <coop_thread_bottom_hierarchy>`.
|
||||
|
||||
.. _coop_thread_top_hierarchy:
|
||||
|
||||
.. figure:: ../../data/how-to/hip_runtime_api/cooperative_groups/thread_hierarchy_coop_top.svg
|
||||
:alt: Diagram depicting nested rectangles of varying color. The outermost one
|
||||
titled "Grid", inside sets of different sized rectangles layered on
|
||||
one another titled "Block". Each "Block" containing sets of uniform
|
||||
rectangles layered on one another titled "Warp". Each of the "Warp"
|
||||
titled rectangles filled with downward pointing arrows inside.
|
||||
|
||||
Cooperative group thread hierarchy in grids.
|
||||
|
||||
The **multi grid** is an abstraction of potentially multiple simultaneous
|
||||
launches of the same kernel over multiple devices. The **grid** in cooperative
|
||||
groups is a single dispatch of kernels for execution like the original grid.
|
||||
|
||||
.. note::
|
||||
|
||||
* The ability to synchronize over a grid or multi grid requires the kernel to
|
||||
be launched using the specific cooperative groups API.
|
||||
|
||||
* Multi grid deprecated since ROCm 5.0.
|
||||
|
||||
The **block** is the same as the :ref:`inherent_thread_model` block entity.
|
||||
|
||||
.. note::
|
||||
|
||||
Explicit warp-level thread handling is absent from the Cooperative groups API. In order to exploit the known hardware SIMD width on which built-in functionality translates to simpler logic, you can use the group partitioning part of the API, such as ``tiled_partition``.
|
||||
|
||||
.. _coop_thread_bottom_hierarchy:
|
||||
|
||||
.. figure:: ../../data/how-to/hip_runtime_api/cooperative_groups/thread_hierarchy_coop_bottom.svg
|
||||
:alt: The new level between block thread and threads.
|
||||
|
||||
Cooperative group thread hierarchy in blocks.
|
||||
|
||||
The cooperative groups API introduce a new level between block thread and threads. The :ref:`thread-block tile <coop_thread_block_tile>` give the opportunity to have tiles in the thread block, while the :ref:`coalesced group <coop_coalesced_groups>` holds the active threads of the parent group. These groups further discussed in the :ref:`groups types <coop_group_types>` section.
|
||||
|
||||
For details on memory model, check the :ref:`memory model description <memory_hierarchy>`.
|
||||
|
||||
.. _coop_group_types:
|
||||
|
||||
Group types
|
||||
===========
|
||||
|
||||
Group types are based on the levels of synchronization and data sharing among threads.
|
||||
|
||||
Thread-block group
|
||||
------------------
|
||||
|
||||
Represents an intra-block cooperative groups type where the participating threads within the group are the same threads that participated in the currently executing ``block``.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
class thread_block;
|
||||
|
||||
Constructed via:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
thread_block g = this_thread_block();
|
||||
|
||||
The ``group_index()`` , ``thread_index()`` , ``thread_rank()`` , ``size()``, ``cg_type()``, ``is_valid()`` , ``sync()`` and ``group_dim()`` member functions are public of the thread_block class. For further details, check the :ref:`thread_block references <thread_block_ref>` .
|
||||
|
||||
Grid group
|
||||
------------
|
||||
|
||||
Represents an inter-block cooperative groups type where the group's participating threads span multiple blocks running the same kernel on the same device. Use the cooperative launch API to enable synchronization across the grid group.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
class grid_group;
|
||||
|
||||
Constructed via:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
grid_group g = this_grid();
|
||||
|
||||
The ``thread_rank()`` , ``size()``, ``cg_type()``, ``is_valid()`` and ``sync()`` member functions
|
||||
are public of the ``grid_group`` class. For further details, check the :ref:`grid_group references <grid_group_ref>`.
|
||||
|
||||
Multi-grid group
|
||||
------------------
|
||||
|
||||
Represents an inter-device cooperative groups type where the participating threads within the group span multiple devices that run the same kernel on the devices. Use the cooperative launch API to enable synchronization across the multi-grid group.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
class multi_grid_group;
|
||||
|
||||
Constructed via:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// Kernel must be launched with the cooperative multi-device API
|
||||
multi_grid_group g = this_multi_grid();
|
||||
|
||||
The ``num_grids()`` , ``grid_rank()`` , ``thread_rank()``, ``size()``, ``cg_type()``, ``is_valid()`` ,
|
||||
and ``sync()`` member functions are public of the ``multi_grid_group`` class. For
|
||||
further details check the :ref:`multi_grid_group references <multi_grid_group_ref>` .
|
||||
|
||||
.. _coop_thread_block_tile:
|
||||
|
||||
Thread-block tile
|
||||
------------------
|
||||
|
||||
This constructs a templated class derived from ``thread_group``. The template defines the tile
|
||||
size of the new thread group at compile time. This group type also supports sub-wave level intrinsics.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
template <unsigned int Size, typename ParentT = void>
|
||||
class thread_block_tile;
|
||||
|
||||
Constructed via:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
template <unsigned int Size, typename ParentT>
|
||||
_CG_QUALIFIER thread_block_tile<Size, ParentT> tiled_partition(const ParentT& g)
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
* Size must be a power of 2 and not larger than warp (wavefront) size.
|
||||
* ``shfl()`` functions support integer or float type.
|
||||
|
||||
The ``thread_rank()`` , ``size()``, ``cg_type()``, ``is_valid()``, ``sync()``, ``meta_group_rank()``, ``meta_group_size()``, ``shfl()``, ``shfl_down()``, ``shfl_up()``, ``shfl_xor()``, ``ballot()``, ``any()``, ``all()``, ``match_any()`` and ``match_all()`` member functions are public of the ``thread_block_tile`` class. For further details, check the :ref:`thread_block_tile references <thread_block_tile_ref>` .
|
||||
|
||||
.. _coop_coalesced_groups:
|
||||
|
||||
Coalesced groups
|
||||
------------------
|
||||
|
||||
Threads (64 threads on CDNA and 32 threads on RDNA) in a warp cannot execute different instructions simultaneously, so conditional branches are executed serially within the warp. When threads encounter a conditional branch, they can diverge, resulting in some threads being disabled if they do not meet the condition to execute that branch. The active threads are referred to as coalesced, and coalesced group represents an active thread group within a warp.
|
||||
|
||||
.. note::
|
||||
|
||||
The NVIDIA GPU's independent thread scheduling presents the appearance that threads on different branches execute concurrently.
|
||||
|
||||
.. warning::
|
||||
|
||||
AMD GPUs do not support independent thread scheduling. Some CUDA application can rely on this feature and the ported HIP version on AMD GPUs can deadlock, when they try to make use of independent thread scheduling.
|
||||
|
||||
This group type also supports sub-wave level intrinsics.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
class coalesced_group;
|
||||
|
||||
Constructed via:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
coalesced_group active = coalesced_threads();
|
||||
|
||||
.. note::
|
||||
|
||||
``shfl()`` functions support integer or float type.
|
||||
|
||||
The ``thread_rank()`` , ``size()``, ``cg_type()``, ``is_valid()``, ``sync()``, ``meta_group_rank()``, ``meta_group_size()``, ``shfl()``, ``shfl_down()``, ``shfl_up()``, ``ballot()``, ``any()``, ``all()``, ``match_any()`` and ``match_all()`` member functions are public of the ``coalesced_group`` class. For more information, see :ref:`coalesced_group references <coalesced_group_ref>` .
|
||||
|
||||
Cooperative groups simple example
|
||||
=================================
|
||||
|
||||
The difference to the original block model in the ``reduce_sum`` device function is the following.
|
||||
|
||||
.. tab-set::
|
||||
.. tab-item:: Original Block
|
||||
:sync: original-block
|
||||
|
||||
.. code-block:: cuda
|
||||
|
||||
__device__ int reduce_sum(int *shared, int val) {
|
||||
|
||||
// Thread ID
|
||||
const unsigned int thread_id = threadIdx.x;
|
||||
|
||||
// Every iteration the number of active threads
|
||||
// halves, until we processed all values
|
||||
for(unsigned int i = blockDim.x / 2; i > 0; i /= 2) {
|
||||
// Store value in shared memory with thread ID
|
||||
shared[thread_id] = val;
|
||||
|
||||
// Synchronize all threads
|
||||
__syncthreads();
|
||||
|
||||
// Active thread sum up
|
||||
if(thread_id < i)
|
||||
val += shared[thread_id + i];
|
||||
|
||||
// Synchronize all threads in the group
|
||||
__syncthreads();
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
.. tab-item:: Cooperative groups
|
||||
:sync: cooperative-groups
|
||||
|
||||
.. code-block:: cuda
|
||||
|
||||
__device__ int reduce_sum(thread_group g,
|
||||
int *shared,
|
||||
int val) {
|
||||
|
||||
// Thread ID
|
||||
const unsigned int group_thread_id = g.thread_rank();
|
||||
|
||||
// Every iteration the number of active threads
|
||||
// halves, until we processed all values
|
||||
for(unsigned int i = g.size() / 2; i > 0; i /= 2) {
|
||||
// Store value in shared memroy with thread ID
|
||||
shared[group_thread_id] = val;
|
||||
|
||||
// Synchronize all threads in the group
|
||||
g.sync();
|
||||
|
||||
// Active thread sum up
|
||||
if(group_thread_id < i)
|
||||
val += shared[group_thread_id + i];
|
||||
|
||||
// Synchronize all threads in the group
|
||||
g.sync();
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
The ``reduce_sum()`` function call and input data initialization difference to the original block model is the following.
|
||||
|
||||
.. tab-set::
|
||||
.. tab-item:: Original Block
|
||||
:sync: original-block
|
||||
|
||||
.. code-block:: cuda
|
||||
|
||||
__global__ void sum_kernel(...) {
|
||||
|
||||
// ...
|
||||
|
||||
// Workspace array in shared memory
|
||||
__shared__ unsigned int workspace[2048];
|
||||
|
||||
// ...
|
||||
|
||||
// Perform reduction
|
||||
output = reduce_sum(workspace, input);
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
.. tab-item:: Cooperative groups
|
||||
:sync: cooperative-groups
|
||||
|
||||
.. code-block:: cuda
|
||||
|
||||
__global__ void sum_kernel(...) {
|
||||
|
||||
// ...
|
||||
|
||||
// Workspace array in shared memory
|
||||
__shared__ unsigned int workspace[2048];
|
||||
|
||||
// ...
|
||||
|
||||
// Initialize the thread_block
|
||||
thread_block thread_block_group = this_thread_block();
|
||||
// Perform reduction
|
||||
output = reduce_sum(thread_block_group, workspace, input);
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
At the device function, the input group type is the ``thread_group``, which is the parent class of all the cooperative groups type. With this, you can write generic functions, which can work with any type of cooperative groups.
|
||||
|
||||
.. _coop_synchronization:
|
||||
|
||||
Synchronization
|
||||
===============
|
||||
|
||||
With each group type, the synchronization requires using the correct cooperative groups launch API.
|
||||
|
||||
**Check the kernel launch capability**
|
||||
|
||||
.. tab-set::
|
||||
.. tab-item:: Thread-block
|
||||
:sync: thread-block
|
||||
|
||||
Do not need kernel launch validation.
|
||||
|
||||
.. tab-item:: Grid
|
||||
:sync: grid
|
||||
|
||||
Confirm the cooperative launch capability on the single AMD GPU:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
int device = 0;
|
||||
int supports_coop_launch = 0;
|
||||
// Check support
|
||||
// Use hipDeviceAttributeCooperativeMultiDeviceLaunch when launching across multiple devices
|
||||
HIP_CHECK(hipGetDevice(&device));
|
||||
HIP_CHECK(
|
||||
hipDeviceGetAttribute(&supports_coop_launch, hipDeviceAttributeCooperativeLaunch, device));
|
||||
if(!supports_coop_launch)
|
||||
{
|
||||
std::cout << "Skipping, device " << device << " does not support cooperative groups"
|
||||
<< std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
.. tab-item:: Multi-grid
|
||||
:sync: multi-grid
|
||||
|
||||
Confirm the cooperative launch capability over multiple GPUs:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// Check support of cooperative groups
|
||||
std::vector<int> deviceIDs;
|
||||
for(int deviceID = 0; deviceID < device_count; deviceID++) {
|
||||
#ifdef __HIP_PLATFORM_AMD__
|
||||
int supports_coop_launch = 0;
|
||||
HIP_CHECK(
|
||||
hipDeviceGetAttribute(
|
||||
&supports_coop_launch,
|
||||
hipDeviceAttributeCooperativeMultiDeviceLaunch,
|
||||
deviceID));
|
||||
if(!supports_coop_launch) {
|
||||
std::cout << "Skipping, device " << deviceID << " does not support cooperative groups"
|
||||
<< std::endl;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
std::cout << deviceID << std::endl;
|
||||
// Collect valid deviceIDs.
|
||||
deviceIDs.push_back(deviceID);
|
||||
}
|
||||
}
|
||||
|
||||
**Kernel launch**
|
||||
|
||||
.. tab-set::
|
||||
.. tab-item:: Thread-block
|
||||
:sync: thread-block
|
||||
|
||||
You can access the new block representation using the original kernel launch methods.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
void* params[] = {&d_vector, &d_block_reduced, &d_partition_reduced};
|
||||
// Launching kernel from host.
|
||||
HIP_CHECK(hipLaunchKernelGGL(vector_reduce_kernel<partition_size>,
|
||||
dim3(num_blocks),
|
||||
dim3(threads_per_block),
|
||||
0,
|
||||
hipStreamDefault,
|
||||
&d_vector,
|
||||
&d_block_reduced,
|
||||
&d_partition_reduced));
|
||||
|
||||
.. tab-item:: Grid
|
||||
:sync: grid
|
||||
|
||||
Launch the cooperative kernel on a single GPU:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
void* params[] = {};
|
||||
// Launching kernel from host.
|
||||
HIP_CHECK(hipLaunchCooperativeKernel(vector_reduce_kernel<partition_size>,
|
||||
dim3(num_blocks),
|
||||
dim3(threads_per_block),
|
||||
0,
|
||||
0,
|
||||
hipStreamDefault));
|
||||
|
||||
.. tab-item:: Multi-grid
|
||||
:sync: multi-grid
|
||||
|
||||
Launch the cooperative kernel over multiple GPUs:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
hipLaunchParams *launchParamsList = (hipLaunchParams*)malloc(sizeof(hipLaunchParams) * deviceIDs.size());
|
||||
for(int deviceID : deviceIDs) {
|
||||
|
||||
// Set device
|
||||
HIP_CHECK(hipSetDevice(deviceID));
|
||||
|
||||
// Create stream
|
||||
hipStream_t stream;
|
||||
HIP_CHECK(hipStreamCreate(&stream));
|
||||
|
||||
// Parameters
|
||||
void* params[] = {&(d_vector[deviceID]), &(d_block_reduced[deviceID]), &(d_partition_reduced[deviceID])};
|
||||
|
||||
// Set launchParams
|
||||
launchParamsList[deviceID].func = (void*)vector_reduce_kernel<partition_size>;
|
||||
launchParamsList[deviceID].gridDim = dim3(1);
|
||||
launchParamsList[deviceID].blockDim = dim3(threads_per_block);
|
||||
launchParamsList[deviceID].sharedMem = 0;
|
||||
launchParamsList[deviceID].stream = stream;
|
||||
launchParamsList[deviceID].args = params;
|
||||
}
|
||||
|
||||
HIP_CHECK(hipLaunchCooperativeKernelMultiDevice(launchParamsList,
|
||||
(int)deviceIDs.size(),
|
||||
hipCooperativeLaunchMultiDeviceNoPreSync));
|
||||
|
||||
**Device side synchronization**
|
||||
|
||||
.. tab-set::
|
||||
.. tab-item:: Thread-block
|
||||
:sync: thread-block
|
||||
|
||||
The device side code of the thread_block synchronization over single GPUs:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
thread_block g = this_thread_block();
|
||||
g.sync();
|
||||
|
||||
.. tab-item:: Grid
|
||||
:sync: grid
|
||||
|
||||
The device side code of the grid synchronization over single GPUs:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
grid_group grid = this_grid();
|
||||
grid.sync();
|
||||
|
||||
.. tab-item:: Multi-grid
|
||||
:sync: multi-grid
|
||||
|
||||
The device side code of the multi-grid synchronization over multiple GPUs:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
multi_grid_group multi_grid = this_multi_grid();
|
||||
multi_grid.sync();
|
||||
|
||||
Unsupported NVIDIA CUDA features
|
||||
================================
|
||||
|
||||
HIP doesn't support the following NVIDIA CUDA optional headers:
|
||||
|
||||
* ``cooperative_groups/memcpy_async.h``
|
||||
* ``cooperative_groups/reduce.h``
|
||||
* ``cooperative_groups/scan.h``
|
||||
|
||||
HIP doesn't support the following CUDA class in ``cooperative_groups`` namespace:
|
||||
|
||||
* ``cluster_group``
|
||||
|
||||
HIP doesn't support the following CUDA functions/operators in ``cooperative_groups`` namespace:
|
||||
|
||||
* ``synchronize``
|
||||
* ``memcpy_async``
|
||||
* ``wait`` and ``wait_prior``
|
||||
* ``barrier_arrive`` and ``barrier_wait``
|
||||
* ``invoke_one`` and ``invoke_one_broadcast``
|
||||
* ``reduce``
|
||||
* ``reduce_update_async`` and ``reduce_store_async``
|
||||
* Reduce operators ``plus`` , ``less`` , ``greater`` , ``bit_and`` , ``bit_xor`` and ``bit_or``
|
||||
* ``inclusive_scan`` and ``exclusive_scan``
|
||||
@@ -0,0 +1,138 @@
|
||||
.. meta::
|
||||
:description: Error Handling
|
||||
:keywords: AMD, ROCm, HIP, error handling, error
|
||||
|
||||
.. _error_handling:
|
||||
|
||||
********************************************************************************
|
||||
Error handling
|
||||
********************************************************************************
|
||||
|
||||
HIP provides functionality to detect, report, and manage errors that occur
|
||||
during the execution of HIP runtime functions or when launching kernels. Every
|
||||
HIP runtime function, apart from launching kernels, has :cpp:type:`hipError_t`
|
||||
as return type. :cpp:func:`hipGetLastError` and :cpp:func:`hipPeekAtLastError`
|
||||
can be used for catching errors from kernel launches, as kernel launches don't
|
||||
return an error directly. HIP maintains an internal state, that includes the
|
||||
last error code. :cpp:func:`hipGetLastError` returns and resets that error to
|
||||
``hipSuccess``, while :cpp:func:`hipPeekAtLastError` just returns the error
|
||||
without changing it. To get a human readable version of the errors,
|
||||
:cpp:func:`hipGetErrorString` and :cpp:func:`hipGetErrorName` can be used.
|
||||
|
||||
.. note::
|
||||
|
||||
:cpp:func:`hipGetLastError` returns the returned error code of the last HIP
|
||||
runtime API call even if it's ``hipSuccess``, while ``cudaGetLastError``
|
||||
returns the error returned by any of the preceding CUDA APIs in the same
|
||||
host thread. :cpp:func:`hipGetLastError` behavior will be matched with
|
||||
``cudaGetLastError`` in ROCm release 7.0.
|
||||
|
||||
Best practices of HIP error handling:
|
||||
|
||||
1. Check errors after each API call - Avoid error propagation.
|
||||
2. Use macros for error checking - Check :ref:`hip_check_macros`.
|
||||
3. Handle errors gracefully - Free resources and provide meaningful error
|
||||
messages to the user.
|
||||
|
||||
For more details on the error handling functions, see :ref:`error handling
|
||||
functions reference page <error_handling_reference>`.
|
||||
|
||||
For a list of all error codes, see :ref:`HIP error codes <hip_error_codes>`.
|
||||
|
||||
.. _hip_check_macros:
|
||||
|
||||
HIP check macros
|
||||
================================================================================
|
||||
|
||||
HIP uses check macros to simplify error checking and reduce code duplication.
|
||||
The ``HIP_CHECK`` macros are mainly used to detect and report errors. It can
|
||||
also exit from application with ``exit(1);`` function call after the error
|
||||
print. The ``HIP_CHECK`` macro example:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#define HIP_CHECK(expression) \
|
||||
{ \
|
||||
const hipError_t status = expression; \
|
||||
if(status != hipSuccess){ \
|
||||
std::cerr << "HIP error " \
|
||||
<< status << ": " \
|
||||
<< hipGetErrorString(status) \
|
||||
<< " at " << __FILE__ << ":" \
|
||||
<< __LINE__ << std::endl; \
|
||||
} \
|
||||
}
|
||||
|
||||
Complete example
|
||||
================================================================================
|
||||
|
||||
A complete example to demonstrate the error handling with a simple addition of
|
||||
two values kernel:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
#define HIP_CHECK(expression) \
|
||||
{ \
|
||||
const hipError_t status = expression; \
|
||||
if(status != hipSuccess){ \
|
||||
std::cerr << "HIP error " \
|
||||
<< status << ": " \
|
||||
<< hipGetErrorString(status) \
|
||||
<< " at " << __FILE__ << ":" \
|
||||
<< __LINE__ << std::endl; \
|
||||
} \
|
||||
}
|
||||
|
||||
// Addition of two values.
|
||||
__global__ void add(int *a, int *b, int *c, size_t size) {
|
||||
const size_t index = threadIdx.x + blockDim.x * blockIdx.x;
|
||||
if(index < size) {
|
||||
c[index] += a[index] + b[index];
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
constexpr int numOfBlocks = 256;
|
||||
constexpr int threadsPerBlock = 256;
|
||||
constexpr size_t arraySize = 1U << 16;
|
||||
|
||||
std::vector<int> a(arraySize), b(arraySize), c(arraySize);
|
||||
int *d_a, *d_b, *d_c;
|
||||
|
||||
// Setup input values.
|
||||
std::fill(a.begin(), a.end(), 1);
|
||||
std::fill(b.begin(), b.end(), 2);
|
||||
|
||||
// Allocate device copies of a, b and c.
|
||||
HIP_CHECK(hipMalloc(&d_a, arraySize * sizeof(*d_a)));
|
||||
HIP_CHECK(hipMalloc(&d_b, arraySize * sizeof(*d_b)));
|
||||
HIP_CHECK(hipMalloc(&d_c, arraySize * sizeof(*d_c)));
|
||||
|
||||
// Copy input values to device.
|
||||
HIP_CHECK(hipMemcpy(d_a, &a, arraySize * sizeof(*d_a), hipMemcpyHostToDevice));
|
||||
HIP_CHECK(hipMemcpy(d_b, &b, arraySize * sizeof(*d_b), hipMemcpyHostToDevice));
|
||||
|
||||
// Launch add() kernel on GPU.
|
||||
hipLaunchKernelGGL(add, dim3(numOfBlocks), dim3(threadsPerBlock), 0, 0, d_a, d_b, d_c, arraySize);
|
||||
// Check the kernel launch
|
||||
HIP_CHECK(hipGetLastError());
|
||||
// Check for kernel execution error
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
|
||||
// Copy the result back to the host.
|
||||
HIP_CHECK(hipMemcpy(&c, d_c, arraySize * sizeof(*d_c), hipMemcpyDeviceToHost));
|
||||
|
||||
// Cleanup allocated memory.
|
||||
HIP_CHECK(hipFree(d_a));
|
||||
HIP_CHECK(hipFree(d_b));
|
||||
HIP_CHECK(hipFree(d_c));
|
||||
|
||||
// Print the result.
|
||||
std::cout << a[0] << " + " << b[0] << " = " << c[0] << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
.. meta::
|
||||
:description: HIP provides an external resource interoperability API that
|
||||
allows efficient data sharing between HIP's computing power and
|
||||
OpenGL's graphics rendering.
|
||||
:keywords: AMD, ROCm, HIP, external, interop, interoperability
|
||||
|
||||
*******************************************************************************
|
||||
External resource interoperability
|
||||
*******************************************************************************
|
||||
|
||||
This feature allows HIP to work with resources -- like memory and semaphores --
|
||||
created by other APIs. This means resources can be used from APIs like CUDA,
|
||||
OpenCL and Vulkan within HIP, making it easier to integrate HIP into existing
|
||||
projects.
|
||||
|
||||
To use external resources in HIP, you typically follow these steps:
|
||||
|
||||
- Import resources from other APIs using HIP provided functions
|
||||
- Use external resources as if they were created in HIP
|
||||
- Destroy the HIP resource object to clean up
|
||||
|
||||
Semaphore Functions
|
||||
===============================================================================
|
||||
|
||||
Semaphore functions are essential for synchronization in parallel computing.
|
||||
These functions facilitate communication and coordination between different
|
||||
parts of a program or between different programs. By managing semaphores, tasks
|
||||
are executed in the correct order, and resources are utilized effectively.
|
||||
Semaphore functions ensure smooth operation, preventing conflicts and
|
||||
maintaining the integrity of processes; upholding the integrity and performance
|
||||
of concurrent processes.
|
||||
|
||||
External semaphore functions can be used in HIP as described in :ref:`external_resource_interoperability_reference`.
|
||||
|
||||
Memory Functions
|
||||
===============================================================================
|
||||
|
||||
HIP external memory functions focus on the efficient sharing and management of
|
||||
memory resources. These functions enable importing memory created by external
|
||||
systems, enabling the HIP program to use this memory seamlessly. Memory
|
||||
functions include mapping memory for effective use and ensuring proper cleanup
|
||||
to prevent resource leaks. This is critical for performance, particularly in
|
||||
applications handling large datasets or complex structures such as textures in
|
||||
graphics. Proper memory management ensures stability and efficient resource
|
||||
utilization.
|
||||
|
||||
Example
|
||||
===============================================================================
|
||||
|
||||
ROCm examples include a
|
||||
`HIP--Vulkan interoperation example <https://github.com/ROCm/rocm-examples/tree/develop/HIP-Basic/vulkan_interop>`_
|
||||
demonstrates how to perform interoperation between HIP and Vulkan.
|
||||
|
||||
In this example, a simple HIP kernel is used to compute a sine wave, which is
|
||||
then rendered to a window as a graphical output using Vulkan. The process
|
||||
requires several initialization steps, such as setting up a HIP context,
|
||||
creating a Vulkan instance, and configuring the GPU device and queue. After
|
||||
these initial steps, the kernel executes the sine wave computation, and Vulkan
|
||||
continuously updates the window framebuffer to display the computed data until
|
||||
the window is closed.
|
||||
|
||||
The following code converts a Vulkan memory handle to its equivalent HIP
|
||||
handle. The input ``VkDeviceMemory`` and the created HIP memory represents the
|
||||
same physical area of GPU memory, through the handles of each respective API.
|
||||
Writing to the buffer in one API will allow us to read the results through the
|
||||
other. Note that access to the buffer should be synchronized between the APIs,
|
||||
for example using queue syncs or semaphores.
|
||||
|
||||
.. <!-- spellcheck-disable -->
|
||||
|
||||
.. literalinclude:: ../../tools/example_codes/external_interop.hip
|
||||
:start-after: // [Sphinx vulkan memory to hip start]
|
||||
:end-before: // [Sphinx vulkan memory to hip end]
|
||||
:language: cpp
|
||||
|
||||
.. <!-- spellcheck-enable -->
|
||||
|
||||
The Vulkan semaphore is converted to HIP semaphore shown in the following
|
||||
example. Signaling on the semaphore in one API will allow the other API to wait
|
||||
on it, which is how we can guarantee synchronized access to resources in a
|
||||
cross-API manner.
|
||||
|
||||
.. <!-- spellcheck-disable -->
|
||||
|
||||
.. literalinclude:: ../../tools/example_codes/external_interop.hip
|
||||
:start-after: // [Sphinx semaphore import start]
|
||||
:end-before: // [Sphinx semaphore import end]
|
||||
:language: cpp
|
||||
|
||||
.. <!-- spellcheck-enable -->
|
||||
|
||||
When the HIP external memory is exported from Vulkan and imported to HIP, it is
|
||||
not yet ready for use. The Vulkan handle is shared, allowing for memory sharing
|
||||
rather than copying during the export process. To actually use the memory, we
|
||||
need to map it to a pointer so that we may pass it to the kernel so that it can
|
||||
be read from and written to. The external memory map to HIP in the following
|
||||
example:
|
||||
|
||||
.. <!-- spellcheck-disable -->
|
||||
|
||||
.. literalinclude:: ../../tools/example_codes/external_interop.hip
|
||||
:start-after: // [Sphinx map external memory start]
|
||||
:end-before: // [Sphinx map external memory end]
|
||||
:language: cpp
|
||||
|
||||
.. <!-- spellcheck-enable -->
|
||||
|
||||
Wait for buffer is ready and not under modification at Vulkan side:
|
||||
|
||||
.. <!-- spellcheck-disable -->
|
||||
|
||||
.. literalinclude:: ../../tools/example_codes/external_interop.hip
|
||||
:start-after: // [Sphinx wait semaphore start]
|
||||
:end-before: // [Sphinx wait semaphore end]
|
||||
:language: cpp
|
||||
|
||||
.. <!-- spellcheck-enable -->
|
||||
|
||||
The sinewave kernel implementation:
|
||||
|
||||
.. <!-- spellcheck-disable -->
|
||||
|
||||
.. literalinclude:: ../../tools/example_codes/external_interop.hip
|
||||
:start-after: [Sphinx sinewave kernel start]
|
||||
:end-before: // [Sphinx sinewave kernel end]
|
||||
:language: cpp
|
||||
|
||||
.. <!-- spellcheck-enable -->
|
||||
|
||||
Signal to Vulkan that we are done with the buffer and that it can proceed with
|
||||
rendering:
|
||||
|
||||
.. <!-- spellcheck-disable -->
|
||||
|
||||
.. literalinclude:: ../../tools/example_codes/external_interop.hip
|
||||
:start-after: // [Sphinx signal semaphore start]
|
||||
:end-before: // [Sphinx signal semaphore end]
|
||||
:language: cpp
|
||||
|
||||
.. <!-- spellcheck-enable -->
|
||||
@@ -0,0 +1,516 @@
|
||||
.. meta::
|
||||
:description: This chapter describes how to use HIP graphs and highlights their use cases.
|
||||
:keywords: ROCm, HIP, graph, stream
|
||||
|
||||
.. _how_to_HIP_graph:
|
||||
|
||||
********************************************************************************
|
||||
HIP graphs
|
||||
********************************************************************************
|
||||
|
||||
.. note::
|
||||
The HIP graph API is currently in Beta. Some features can change and might
|
||||
have outstanding issues. Not all features supported by CUDA graphs are yet
|
||||
supported. For a list of all currently supported functions see the
|
||||
:ref:`HIP graph API documentation<graph_management_reference>`.
|
||||
|
||||
HIP graphs are an alternative way of executing tasks on a GPU that can provide
|
||||
performance benefits over launching kernels using the standard
|
||||
method via streams. A HIP graph is made up of nodes and edges. The nodes of a
|
||||
HIP graph represent the operations performed, while the edges mark dependencies
|
||||
between those operations.
|
||||
|
||||
The nodes can be one of the following:
|
||||
|
||||
- empty nodes
|
||||
- nested graphs
|
||||
- kernel launches
|
||||
- host-side function calls
|
||||
- HIP memory functions (copy, memset, ...)
|
||||
- HIP events
|
||||
- signalling or waiting on external semaphores
|
||||
|
||||
.. note::
|
||||
The available node types are specified by :cpp:enum:`hipGraphNodeType`.
|
||||
|
||||
The following figure visualizes the concept of graphs, compared to using streams.
|
||||
|
||||
.. figure:: ../../data/how-to/hip_runtime_api/hipgraph/hip_graph.svg
|
||||
:alt: Diagram depicting the difference between using streams to execute
|
||||
kernels with dependencies, resolved by explicitly synchronizing,
|
||||
or using graphs, where the edges denote the dependencies.
|
||||
|
||||
The standard method of launching kernels incurs a small overhead for each
|
||||
iteration of the operation involved. That overhead is negligible, when the
|
||||
kernel is launched directly with the HIP C/C++ API, but depending on the
|
||||
framework used, there can be several levels of redirection, until the actual
|
||||
kernel is launched by the HIP runtime, leading to significant overhead.
|
||||
Especially for some AI frameworks, a GPU kernel might run faster than the time
|
||||
it takes for the framework to set up and launch the kernel, and so the overhead
|
||||
of repeatedly launching kernels can have a significant impact on performance.
|
||||
|
||||
HIP graphs are designed to address this issue, by predefining the HIP API calls
|
||||
and their dependencies with a graph, and performing most of the initialization
|
||||
beforehand. Launching a graph only requires a single call, after which the
|
||||
HIP runtime takes care of executing the operations within the graph.
|
||||
Graphs can provide additional performance benefits, by enabling optimizations
|
||||
that are only possible when knowing the dependencies between the operations.
|
||||
|
||||
.. figure:: ../../data/how-to/hip_runtime_api/hipgraph/hip_graph_speedup.svg
|
||||
:alt: Diagram depicting the speed up achievable with HIP graphs compared to
|
||||
HIP streams when launching many short-running kernels.
|
||||
|
||||
Qualitative presentation of the execution time of many short-running kernels
|
||||
when launched using HIP stream versus HIP graph. This does not include the
|
||||
time needed to set up the graph.
|
||||
|
||||
Using HIP graphs
|
||||
================================================================================
|
||||
|
||||
There are two different ways of creating graphs: Capturing kernel launches from
|
||||
a stream, or explicitly creating graphs. The difference between the two
|
||||
approaches is explained later in this chapter.
|
||||
|
||||
The general flow for using HIP graphs includes the following steps.
|
||||
|
||||
#. Create a :cpp:type:`hipGraph_t` graph template using one of the two approaches described in this chapter
|
||||
#. Create a :cpp:type:`hipGraphExec_t` executable instance of the graph template using :cpp:func:`hipGraphInstantiate`
|
||||
#. Use :cpp:func:`hipGraphLaunch` to launch the executable graph to a stream
|
||||
#. After execution completes free and destroy graph resources
|
||||
|
||||
The first two steps are the initial setup and only need to be executed once. First
|
||||
step is the definition of the operations (nodes) and the dependencies (edges)
|
||||
between them. The second step is the instantiation of the graph. This takes care
|
||||
of validating and initializing the graph, to reduce the overhead when executing
|
||||
the graph. The third step is the execution of the graph, which takes care of
|
||||
launching all the kernels and executing the operations while respecting their
|
||||
dependencies and necessary synchronizations as specified.
|
||||
|
||||
Because HIP graphs require some setup and initialization overhead before their
|
||||
first execution, graphs only provide a benefit for workloads that require
|
||||
many iterations to complete.
|
||||
|
||||
In both methods the :cpp:type:`hipGraph_t` template for a graph is used to define the graph.
|
||||
In order to actually launch a graph, the template needs to be instantiated using
|
||||
:cpp:func:`hipGraphInstantiate`, which results in an executable graph of type :cpp:type:`hipGraphExec_t`.
|
||||
This executable graph can then be launched with :cpp:func:`hipGraphLaunch`, replaying the
|
||||
operations within the graph. Note, that launching graphs is fundamentally no
|
||||
different to executing other HIP functions on a stream, except for the fact,
|
||||
that scheduling the operations within the graph encompasses less overhead and
|
||||
can enable some optimizations, but they still need to be associated with a stream for execution.
|
||||
|
||||
Memory management
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Memory that is used by operations in graphs can either be pre-allocated or
|
||||
managed within the graph. Graphs can contain nodes that take care of allocating
|
||||
memory on the device or copying memory between the host and the device.
|
||||
Whether you want to pre-allocate the memory or manage it within the graph
|
||||
depends on the use-case. If the graph is executed in a tight loop the
|
||||
performance is usually better when the memory is preallocated, so that it
|
||||
does not need to be reallocated in every iteration.
|
||||
|
||||
The same rules as for normal memory allocations apply for memory allocated and
|
||||
freed by nodes, meaning that the nodes that access memory allocated in a graph
|
||||
must be ordered after allocation and before freeing.
|
||||
|
||||
Memory management within the graph enables the runtime to take care of memory reuse and optimizations.
|
||||
The lifetime of memory managed in a graph begins when the execution reaches the
|
||||
node allocating the memory, and ends when either reaching the corresponding
|
||||
free node within the graph, or after graph execution when a corresponding
|
||||
:cpp:func:`hipFreeAsync` or :cpp:func:`hipFree` call is reached.
|
||||
The memory can also be freed with a free node in a different graph that is
|
||||
associated with the same memory address.
|
||||
|
||||
Unlike device memory that is not associated with a graph, this does not necessarily
|
||||
mean that the freed memory is returned back to the operating system immediately.
|
||||
Graphs can retain a memory pool for quickly reusing memory within the graph.
|
||||
This can be especially useful when memory is freed and reallocated later on
|
||||
within a graph, as that memory doesn't have to be requested from the operating system.
|
||||
It also potentially reduces the total memory footprint of the graph, by reusing the same memory.
|
||||
|
||||
The amount of memory allocated for graph memory pools on a specific device can
|
||||
be queried using :cpp:func:`hipDeviceGetGraphMemAttribute`.
|
||||
In order to return the freed memory :cpp:func:`hipDeviceGraphMemTrim` can be used.
|
||||
This will return any memory that is not in active use by graphs.
|
||||
|
||||
These memory allocations can also be set up to allow access from multiple GPUs,
|
||||
just like normal allocations. HIP then takes care of allocating and mapping the
|
||||
memory to the GPUs. When capturing a graph from a stream, the node sets the
|
||||
accessibility according to :cpp:func:`hipMemPoolSetAccess` at the time of capturing.
|
||||
|
||||
|
||||
Capture graphs from a stream
|
||||
================================================================================
|
||||
|
||||
The easy way to integrate HIP graphs into already existing code is to use
|
||||
:cpp:func:`hipStreamBeginCapture` and :cpp:func:`hipStreamEndCapture` to obtain a :cpp:type:`hipGraph_t`
|
||||
graph template that includes the captured operations.
|
||||
|
||||
When starting to capture operations for a graph using :cpp:func:`hipStreamBeginCapture`,
|
||||
the operations assigned to the stream are captured into a graph instead of being
|
||||
executed. The associated graph is returned when calling :cpp:func:`hipStreamEndCapture`, which
|
||||
also stops capturing operations.
|
||||
In order to capture to an already existing graph use :cpp:func:`hipStreamBeginCaptureToGraph`.
|
||||
|
||||
The functions assigned to the capturing stream are not executed, but instead are
|
||||
captured and defined as nodes in the graph, to be run when the instantiated
|
||||
graph is launched.
|
||||
|
||||
Functions must be associated with a stream in order to be captured.
|
||||
This means that non-HIP API functions are not captured by default, but are
|
||||
executed as standard functions when encountered and not added to the graph.
|
||||
In order to assign host functions to a stream use
|
||||
:cpp:func:`hipLaunchHostFunc`, as shown in the following code example.
|
||||
They will then be captured and defined as a host node in the resulting graph,
|
||||
and won't be executed when encountered.
|
||||
|
||||
Synchronous HIP API calls that are implicitly assigned to the default stream are
|
||||
not permitted while capturing a stream and will return an error. This is
|
||||
because they implicitly synchronize and cause a dependency that can not be
|
||||
captured within the stream. This includes functions like :cpp:func:`hipMalloc`,
|
||||
:cpp:func:`hipMemcpy` and :cpp:func:`hipFree`. In order to capture these to the stream, replace
|
||||
them with the corresponding asynchronous calls like :cpp:func:`hipMallocAsync`, :cpp:func:`hipMemcpyAsync` or :cpp:func:`hipFreeAsync`.
|
||||
|
||||
The general flow for using stream capture to create a graph template is:
|
||||
|
||||
#. Create a stream from which to capture the operations
|
||||
|
||||
#. Call :cpp:func:`hipStreamBeginCapture` before the first operation to be captured
|
||||
|
||||
#. Call :cpp:func:`hipStreamEndCapture` after the last operation to be captured
|
||||
|
||||
#. Define a :cpp:type:`hipGraph_t` graph template to which :cpp:func:`hipStreamEndCapture`
|
||||
passes the captured graph
|
||||
|
||||
The following code is an example of how to use the HIP graph API to capture a
|
||||
graph from a stream.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
#define HIP_CHECK(expression) \
|
||||
{ \
|
||||
const hipError_t status = expression; \
|
||||
if(status != hipSuccess){ \
|
||||
std::cerr << "HIP error " \
|
||||
<< status << ": " \
|
||||
<< hipGetErrorString(status) \
|
||||
<< " at " << __FILE__ << ":" \
|
||||
<< __LINE__ << std::endl; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
__global__ void kernelA(double* arrayA, size_t size){
|
||||
const size_t x = threadIdx.x + blockDim.x * blockIdx.x;
|
||||
if(x < size){arrayA[x] *= 2.0;}
|
||||
};
|
||||
__global__ void kernelB(int* arrayB, size_t size){
|
||||
const size_t x = threadIdx.x + blockDim.x * blockIdx.x;
|
||||
if(x < size){arrayB[x] = 3;}
|
||||
};
|
||||
__global__ void kernelC(double* arrayA, const int* arrayB, size_t size){
|
||||
const size_t x = threadIdx.x + blockDim.x * blockIdx.x;
|
||||
if(x < size){arrayA[x] += arrayB[x];}
|
||||
};
|
||||
|
||||
struct set_vector_args{
|
||||
std::vector<double>& h_array;
|
||||
double value;
|
||||
};
|
||||
|
||||
void set_vector(void* args){
|
||||
set_vector_args h_args{*(reinterpret_cast<set_vector_args*>(args))};
|
||||
|
||||
std::vector<double>& vec{h_args.h_array};
|
||||
vec.assign(vec.size(), h_args.value);
|
||||
}
|
||||
|
||||
int main(){
|
||||
constexpr int numOfBlocks = 1024;
|
||||
constexpr int threadsPerBlock = 1024;
|
||||
constexpr size_t arraySize = 1U << 20;
|
||||
|
||||
// This example assumes that kernelA operates on data that needs to be initialized on
|
||||
// and copied from the host, while kernelB initializes the array that is passed to it.
|
||||
// Both arrays are then used as input to kernelC, where arrayA is also used as
|
||||
// output, that is copied back to the host, while arrayB is only read from and not modified.
|
||||
|
||||
double* d_arrayA;
|
||||
int* d_arrayB;
|
||||
std::vector<double> h_array(arraySize);
|
||||
constexpr double initValue = 2.0;
|
||||
|
||||
hipStream_t captureStream;
|
||||
HIP_CHECK(hipStreamCreate(&captureStream));
|
||||
|
||||
// Start capturing the operations assigned to the stream
|
||||
HIP_CHECK(hipStreamBeginCapture(captureStream, hipStreamCaptureModeGlobal));
|
||||
|
||||
// hipMallocAsync and hipMemcpyAsync are needed, to be able to assign it to a stream
|
||||
HIP_CHECK(hipMallocAsync(&d_arrayA, arraySize*sizeof(double), captureStream));
|
||||
HIP_CHECK(hipMallocAsync(&d_arrayB, arraySize*sizeof(int), captureStream));
|
||||
|
||||
// Assign host function to the stream
|
||||
// Needs a custom struct to pass the arguments
|
||||
set_vector_args args{h_array, initValue};
|
||||
HIP_CHECK(hipLaunchHostFunc(captureStream, set_vector, &args));
|
||||
|
||||
HIP_CHECK(hipMemcpyAsync(d_arrayA, h_array.data(), arraySize*sizeof(double), hipMemcpyHostToDevice, captureStream));
|
||||
|
||||
kernelA<<<numOfBlocks, threadsPerBlock, 0, captureStream>>>(d_arrayA, arraySize);
|
||||
kernelB<<<numOfBlocks, threadsPerBlock, 0, captureStream>>>(d_arrayB, arraySize);
|
||||
kernelC<<<numOfBlocks, threadsPerBlock, 0, captureStream>>>(d_arrayA, d_arrayB, arraySize);
|
||||
|
||||
HIP_CHECK(hipMemcpyAsync(h_array.data(), d_arrayA, arraySize*sizeof(*d_arrayA), hipMemcpyDeviceToHost, captureStream));
|
||||
|
||||
HIP_CHECK(hipFreeAsync(d_arrayA, captureStream));
|
||||
HIP_CHECK(hipFreeAsync(d_arrayB, captureStream));
|
||||
|
||||
// Stop capturing
|
||||
hipGraph_t graph;
|
||||
HIP_CHECK(hipStreamEndCapture(captureStream, &graph));
|
||||
|
||||
// Create an executable graph from the captured graph
|
||||
hipGraphExec_t graphExec;
|
||||
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
|
||||
|
||||
// The graph template can be deleted after the instantiation if it's not needed for later use
|
||||
HIP_CHECK(hipGraphDestroy(graph));
|
||||
|
||||
// Actually launch the graph. The stream does not have
|
||||
// to be the same as the one used for capturing.
|
||||
HIP_CHECK(hipGraphLaunch(graphExec, captureStream));
|
||||
|
||||
// Verify results
|
||||
constexpr double expected = initValue * 2.0 + 3;
|
||||
bool passed = true;
|
||||
for(size_t i = 0; i < arraySize; ++i){
|
||||
if(h_array[i] != expected){
|
||||
passed = false;
|
||||
std::cerr << "Validation failed! Expected " << expected << " got " << h_array[0] << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(passed){
|
||||
std::cerr << "Validation passed." << std::endl;
|
||||
}
|
||||
|
||||
// Free graph and stream resources after usage
|
||||
HIP_CHECK(hipGraphExecDestroy(graphExec));
|
||||
HIP_CHECK(hipStreamDestroy(captureStream));
|
||||
}
|
||||
|
||||
Explicit graph creation
|
||||
================================================================================
|
||||
|
||||
Graphs can also be created directly using the HIP graph API, giving more
|
||||
fine-grained control over the graph. In this case, the graph nodes are created
|
||||
explicitly, together with their parameters and dependencies, which specify the
|
||||
edges of the graph, thereby forming the graph structure.
|
||||
|
||||
The nodes are represented by the generic :cpp:type:`hipGraphNode_t` type. The actual
|
||||
node type is implicitly defined by the specific function used to add the node to
|
||||
the graph, for example :cpp:func:`hipGraphAddKernelNode` See the
|
||||
:ref:`HIP graph API documentation<graph_management_reference>` for the
|
||||
available functions, they are of type ``hipGraphAdd{Type}Node``. Each type of
|
||||
node also has a predefined set of parameters depending on the operation, for
|
||||
example :cpp:class:`hipKernelNodeParams` for a kernel launch. See the
|
||||
:doc:`documentation for the general hipGraphNodeParams type<../../doxygen/html/structhip_graph_node_params>`
|
||||
for a list of available parameter types and their members.
|
||||
|
||||
The general flow for explicitly creating a graph is usually:
|
||||
|
||||
#. Create a graph :cpp:type:`hipGraph_t`
|
||||
|
||||
#. Create the nodes and their parameters and add them to the graph
|
||||
|
||||
#. Define a :cpp:type:`hipGraphNode_t`
|
||||
|
||||
#. Define the parameter struct for the desired operation, by explicitly setting the appropriate struct's members.
|
||||
|
||||
#. Use the appropriate ``hipGraphAdd{Type}Node`` function to add the node to the graph.
|
||||
|
||||
#. The dependencies can be defined when adding the node to the graph, or afterwards by using :cpp:func:`hipGraphAddDependencies`
|
||||
|
||||
The following code example demonstrates how to explicitly create nodes in order to create a graph.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
#define HIP_CHECK(expression) \
|
||||
{ \
|
||||
const hipError_t status = expression; \
|
||||
if(status != hipSuccess){ \
|
||||
std::cerr << "HIP error " \
|
||||
<< status << ": " \
|
||||
<< hipGetErrorString(status) \
|
||||
<< " at " << __FILE__ << ":" \
|
||||
<< __LINE__ << std::endl; \
|
||||
} \
|
||||
}
|
||||
|
||||
__global__ void kernelA(double* arrayA, size_t size){
|
||||
const size_t x = threadIdx.x + blockDim.x * blockIdx.x;
|
||||
if(x < size){arrayA[x] *= 2.0;}
|
||||
};
|
||||
__global__ void kernelB(int* arrayB, size_t size){
|
||||
const size_t x = threadIdx.x + blockDim.x * blockIdx.x;
|
||||
if(x < size){arrayB[x] = 3;}
|
||||
};
|
||||
__global__ void kernelC(double* arrayA, const int* arrayB, size_t size){
|
||||
const size_t x = threadIdx.x + blockDim.x * blockIdx.x;
|
||||
if(x < size){arrayA[x] += arrayB[x];}
|
||||
};
|
||||
|
||||
struct set_vector_args{
|
||||
std::vector<double>& h_array;
|
||||
double value;
|
||||
};
|
||||
|
||||
void set_vector(void* args){
|
||||
set_vector_args h_args{*(reinterpret_cast<set_vector_args*>(args))};
|
||||
|
||||
std::vector<double>& vec{h_args.h_array};
|
||||
vec.assign(vec.size(), h_args.value);
|
||||
}
|
||||
|
||||
int main(){
|
||||
constexpr int numOfBlocks = 1024;
|
||||
constexpr int threadsPerBlock = 1024;
|
||||
size_t arraySize = 1U << 20;
|
||||
|
||||
// The pointers to the device memory don't need to be declared here,
|
||||
// they are contained within the hipMemAllocNodeParams as the dptr member
|
||||
std::vector<double> h_array(arraySize);
|
||||
constexpr double initValue = 2.0;
|
||||
|
||||
// Create graph an empty graph
|
||||
hipGraph_t graph;
|
||||
HIP_CHECK(hipGraphCreate(&graph, 0));
|
||||
|
||||
// Parameters to allocate arrays
|
||||
hipMemAllocNodeParams allocArrayAParams{};
|
||||
allocArrayAParams.poolProps.allocType = hipMemAllocationTypePinned;
|
||||
allocArrayAParams.poolProps.location.type = hipMemLocationTypeDevice;
|
||||
allocArrayAParams.poolProps.location.id = 0; // GPU on which memory resides
|
||||
allocArrayAParams.bytesize = arraySize * sizeof(double);
|
||||
|
||||
hipMemAllocNodeParams allocArrayBParams{};
|
||||
allocArrayBParams.poolProps.allocType = hipMemAllocationTypePinned;
|
||||
allocArrayBParams.poolProps.location.type = hipMemLocationTypeDevice;
|
||||
allocArrayBParams.poolProps.location.id = 0; // GPU on which memory resides
|
||||
allocArrayBParams.bytesize = arraySize * sizeof(int);
|
||||
|
||||
// Add the allocation nodes to the graph. They don't have any dependencies
|
||||
hipGraphNode_t allocNodeA, allocNodeB;
|
||||
HIP_CHECK(hipGraphAddMemAllocNode(&allocNodeA, graph, nullptr, 0, &allocArrayAParams));
|
||||
HIP_CHECK(hipGraphAddMemAllocNode(&allocNodeB, graph, nullptr, 0, &allocArrayBParams));
|
||||
|
||||
// Parameters for the host function
|
||||
// Needs custom struct to pass the arguments
|
||||
set_vector_args args{h_array, initValue};
|
||||
hipHostNodeParams hostParams{};
|
||||
hostParams.fn = set_vector;
|
||||
hostParams.userData = static_cast<void*>(&args);
|
||||
|
||||
// Add the host node that initializes the host array. It also doesn't have any dependencies
|
||||
hipGraphNode_t hostNode;
|
||||
HIP_CHECK(hipGraphAddHostNode(&hostNode, graph, nullptr, 0, &hostParams));
|
||||
|
||||
// Add memory copy node, that copies the initialized host array to the device.
|
||||
// It has to wait for the host array to be initialized and the device memory to be allocated
|
||||
hipGraphNode_t cpyNodeDependencies[] = {allocNodeA, hostNode};
|
||||
hipGraphNode_t cpyToDevNode;
|
||||
HIP_CHECK(hipGraphAddMemcpyNode1D(&cpyToDevNode, graph, cpyNodeDependencies, 1, allocArrayAParams.dptr, h_array.data(), arraySize * sizeof(double), hipMemcpyHostToDevice));
|
||||
|
||||
// Parameters for kernelA
|
||||
hipKernelNodeParams kernelAParams;
|
||||
void* kernelAArgs[] = {&allocArrayAParams.dptr, static_cast<void*>(&arraySize)};
|
||||
kernelAParams.func = reinterpret_cast<void*>(kernelA);
|
||||
kernelAParams.gridDim = numOfBlocks;
|
||||
kernelAParams.blockDim = threadsPerBlock;
|
||||
kernelAParams.sharedMemBytes = 0;
|
||||
kernelAParams.kernelParams = kernelAArgs;
|
||||
kernelAParams.extra = nullptr;
|
||||
|
||||
// Add the node for kernelA. It has to wait for the memory copy to finish, as it depends on the values from the host array.
|
||||
hipGraphNode_t kernelANode;
|
||||
HIP_CHECK(hipGraphAddKernelNode(&kernelANode, graph, &cpyToDevNode, 1, &kernelAParams));
|
||||
|
||||
// Parameters for kernelB
|
||||
hipKernelNodeParams kernelBParams;
|
||||
void* kernelBArgs[] = {&allocArrayBParams.dptr, static_cast<void*>(&arraySize)};
|
||||
kernelBParams.func = reinterpret_cast<void*>(kernelB);
|
||||
kernelBParams.gridDim = numOfBlocks;
|
||||
kernelBParams.blockDim = threadsPerBlock;
|
||||
kernelBParams.sharedMemBytes = 0;
|
||||
kernelBParams.kernelParams = kernelBArgs;
|
||||
kernelBParams.extra = nullptr;
|
||||
|
||||
// Add the node for kernelB. It only has to wait for the memory to be allocated, as it initializes the array.
|
||||
hipGraphNode_t kernelBNode;
|
||||
HIP_CHECK(hipGraphAddKernelNode(&kernelBNode, graph, &allocNodeB, 1, &kernelBParams));
|
||||
|
||||
// Parameters for kernelC
|
||||
hipKernelNodeParams kernelCParams;
|
||||
void* kernelCArgs[] = {&allocArrayAParams.dptr, &allocArrayBParams.dptr, static_cast<void*>(&arraySize)};
|
||||
kernelCParams.func = reinterpret_cast<void*>(kernelC);
|
||||
kernelCParams.gridDim = numOfBlocks;
|
||||
kernelCParams.blockDim = threadsPerBlock;
|
||||
kernelCParams.sharedMemBytes = 0;
|
||||
kernelCParams.kernelParams = kernelCArgs;
|
||||
kernelCParams.extra = nullptr;
|
||||
|
||||
// Add the node for kernelC. It has to wait on both kernelA and kernelB to finish, as it depends on their results.
|
||||
hipGraphNode_t kernelCNode;
|
||||
hipGraphNode_t kernelCDependencies[] = {kernelANode, kernelBNode};
|
||||
HIP_CHECK(hipGraphAddKernelNode(&kernelCNode, graph, kernelCDependencies, 1, &kernelCParams));
|
||||
|
||||
// Copy the results back to the host. Has to wait for kernelC to finish.
|
||||
hipGraphNode_t cpyToHostNode;
|
||||
HIP_CHECK(hipGraphAddMemcpyNode1D(&cpyToHostNode, graph, &kernelCNode, 1, h_array.data(), allocArrayAParams.dptr, arraySize * sizeof(double), hipMemcpyDeviceToHost));
|
||||
|
||||
// Free array of allocNodeA. It needs to wait for the copy to finish, as kernelC stores its results in it.
|
||||
hipGraphNode_t freeNodeA;
|
||||
HIP_CHECK(hipGraphAddMemFreeNode(&freeNodeA, graph, &cpyToHostNode, 1, allocArrayAParams.dptr));
|
||||
// Free array of allocNodeB. It only needs to wait for kernelC to finish, as it is not written back to the host.
|
||||
hipGraphNode_t freeNodeB;
|
||||
HIP_CHECK(hipGraphAddMemFreeNode(&freeNodeB, graph, &kernelCNode, 1, allocArrayBParams.dptr));
|
||||
|
||||
// Instantiate the graph in order to execute it
|
||||
hipGraphExec_t graphExec;
|
||||
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
|
||||
|
||||
// The graph can be freed after the instantiation if it's not needed for other purposes
|
||||
HIP_CHECK(hipGraphDestroy(graph));
|
||||
|
||||
// Actually launch the graph
|
||||
hipStream_t graphStream;
|
||||
HIP_CHECK(hipStreamCreate(&graphStream));
|
||||
HIP_CHECK(hipGraphLaunch(graphExec, graphStream));
|
||||
|
||||
// Verify results
|
||||
constexpr double expected = initValue * 2.0 + 3;
|
||||
bool passed = true;
|
||||
for(size_t i = 0; i < arraySize; ++i){
|
||||
if(h_array[i] != expected){
|
||||
passed = false;
|
||||
std::cerr << "Validation failed! Expected " << expected << " got " << h_array[0] << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(passed){
|
||||
std::cerr << "Validation passed." << std::endl;
|
||||
}
|
||||
|
||||
HIP_CHECK(hipGraphExecDestroy(graphExec));
|
||||
HIP_CHECK(hipStreamDestroy(graphStream));
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
.. meta::
|
||||
:description: Initialization.
|
||||
:keywords: AMD, ROCm, HIP, initialization
|
||||
|
||||
.. _initialization:
|
||||
|
||||
********************************************************************************
|
||||
Initialization
|
||||
********************************************************************************
|
||||
|
||||
The initialization involves setting up the environment and resources needed for
|
||||
using GPUs. The following steps are covered with the initialization:
|
||||
|
||||
- Setting up the HIP runtime
|
||||
|
||||
This includes reading the environment variables set during init, setting up
|
||||
the active or visible devices, loading necessary libraries, setting up
|
||||
internal buffers for memory copies or cooperative launches, initialize the
|
||||
compiler as well as HSA runtime and checks any errors due to lack of resources
|
||||
or no active devices.
|
||||
|
||||
- Querying and setting GPUs
|
||||
|
||||
Identifying and querying the available GPU devices on the system.
|
||||
|
||||
- Setting up contexts
|
||||
|
||||
Creating contexts for each GPU device, which are essential for managing
|
||||
resources and executing kernels. For further details, check the :ref:`context
|
||||
section <context_driver_api>`.
|
||||
|
||||
Initialize the HIP runtime
|
||||
================================================================================
|
||||
|
||||
The HIP runtime is initialized automatically when the first HIP API call is
|
||||
made. However, you can explicitly initialize it using :cpp:func:`hipInit`,
|
||||
to be able to control the timing of the initialization. The manual
|
||||
initialization can be useful to ensure that the GPU is initialized and
|
||||
ready, or to isolate GPU initialization time from other parts of
|
||||
your program.
|
||||
|
||||
.. note::
|
||||
|
||||
You can use :cpp:func:`hipDeviceReset` to delete all streams created, memory
|
||||
allocated, kernels running and events created by the current process. Any new
|
||||
HIP API call initializes the HIP runtime again.
|
||||
|
||||
Querying and setting GPUs
|
||||
================================================================================
|
||||
|
||||
If multiple GPUs are available in the system, you can query and select the
|
||||
desired GPU(s) to use based on device properties, such as size of global memory,
|
||||
size shared memory per block, support of cooperative launch and support of
|
||||
managed memory.
|
||||
|
||||
Querying GPUs
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
The properties of a GPU can be queried using :cpp:func:`hipGetDeviceProperties`,
|
||||
which returns a struct of :cpp:struct:`hipDeviceProp_t`. The properties in the
|
||||
struct can be used to identify a device or give an overview of hardware
|
||||
characteristics, that might make one GPU better suited for the task than others.
|
||||
|
||||
The :cpp:func:`hipGetDeviceCount` function returns the number of available GPUs,
|
||||
which can be used to loop over the available GPUs.
|
||||
|
||||
Example code of querying GPUs:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
|
||||
int deviceCount;
|
||||
if (hipGetDeviceCount(&deviceCount) == hipSuccess){
|
||||
for (int i = 0; i < deviceCount; ++i){
|
||||
hipDeviceProp_t prop;
|
||||
if ( hipGetDeviceProperties(&prop, i) == hipSuccess)
|
||||
std::cout << "Device" << i << prop.name << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Setting the GPU
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
:cpp:func:`hipSetDevice` function select the GPU to be used for subsequent HIP
|
||||
operations. This function performs several key tasks:
|
||||
|
||||
- Context Binding
|
||||
|
||||
Binds the current thread to the context of the specified GPU device. This
|
||||
ensures that all subsequent operations are executed on the selected device.
|
||||
|
||||
- Resource Allocation
|
||||
|
||||
Prepares the device for resource allocation, such as memory allocation and
|
||||
stream creation.
|
||||
|
||||
- Check device availability
|
||||
|
||||
Checks for errors in device selection and returns error if the specified
|
||||
device is not available or not capable of executing HIP operations.
|
||||
@@ -0,0 +1,52 @@
|
||||
.. meta::
|
||||
:description: Memory management and its usage
|
||||
:keywords: AMD, ROCm, HIP, CUDA, memory management
|
||||
|
||||
.. _memory_management:
|
||||
|
||||
********************************************************************************
|
||||
Memory management
|
||||
********************************************************************************
|
||||
|
||||
Memory management is an important part of the HIP runtime API, when creating
|
||||
high-performance applications. Both allocating and copying memory can result in
|
||||
bottlenecks, which can significantly impact performance.
|
||||
|
||||
The programming model is based on a system with a host and a device, each having
|
||||
its own distinct memory. Kernels operate on :ref:`device_memory`, while host functions
|
||||
operate on :ref:`host_memory`.
|
||||
|
||||
The runtime offers functions for allocating, freeing, and copying device memory,
|
||||
along with transferring data between host and device memory.
|
||||
|
||||
Here are the various memory management techniques:
|
||||
|
||||
* :ref:`coherence_control`
|
||||
* :ref:`unified_memory`
|
||||
* :ref:`virtual_memory`
|
||||
* :ref:`stream_ordered_memory_allocator_how-to`
|
||||
|
||||
Memory allocation
|
||||
================================================================================
|
||||
|
||||
The API calls and the resulting allocations are listed here:
|
||||
|
||||
.. list-table:: Memory coherence control
|
||||
:header-rows: 1
|
||||
:align: center
|
||||
|
||||
* - API
|
||||
- Data location
|
||||
- Allocation
|
||||
* - System allocated
|
||||
- Host
|
||||
- :ref:`Pageable <pageable_host_memory>`
|
||||
* - :cpp:func:`hipMallocManaged`
|
||||
- Host
|
||||
- :ref:`Managed <unified_memory>`
|
||||
* - :cpp:func:`hipHostMalloc`
|
||||
- Host
|
||||
- :ref:`Pinned <pinned_host_memory>`
|
||||
* - :cpp:func:`hipMalloc`
|
||||
- Device
|
||||
- Pinned
|
||||
@@ -0,0 +1,178 @@
|
||||
.. meta::
|
||||
:description: HIP coherence control
|
||||
ecosystem ROCm software.
|
||||
:keywords: AMD, ROCm, HIP, host memory
|
||||
|
||||
.. _coherence_control:
|
||||
|
||||
*******************************************************************************
|
||||
Coherence control
|
||||
*******************************************************************************
|
||||
|
||||
Memory coherence describes how memory of a specific part of the system is
|
||||
visible to the other parts of the system. For example, how GPU memory is visible
|
||||
to the CPU and vice versa. In HIP, host and device memory can be allocated with
|
||||
two different types of coherence:
|
||||
|
||||
* **Coarse-grained coherence:** The memory is considered up-to-date only after
|
||||
synchronization performed using :cpp:func:`hipDeviceSynchronize`,
|
||||
:cpp:func:`hipStreamSynchronize`, or any blocking operation that acts on the
|
||||
null stream such as :cpp:func:`hipMemcpy`. To avoid the cache from being
|
||||
accessed by a part of the system while simultaneously being written by
|
||||
another, the memory is made visible only after the caches have been flushed.
|
||||
|
||||
* **Fine-grained coherence:** The memory is coherent even while being modified
|
||||
by a part of the system. Fine-grained coherence ensures that up-to-date data
|
||||
is visible to others regardless of kernel boundaries. This can be useful if
|
||||
both host and device operate on the same data.
|
||||
|
||||
.. note::
|
||||
|
||||
To achieve fine-grained coherence, many AMD GPUs use a limited cache policy,
|
||||
such as leaving these allocations uncached by the GPU or making them read-only.
|
||||
|
||||
Mi200 accelerator's hardware based floating point instructions work on
|
||||
coarse-grained memory regions. Coarse-grained coherence is typically useful in
|
||||
reducing host-device interconnect communication.
|
||||
|
||||
To check the availability of fine- and coarse-grained memory pools, use
|
||||
``rocminfo``:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ rocminfo
|
||||
...
|
||||
*******
|
||||
Agent 1
|
||||
*******
|
||||
Name: AMD EPYC 7742 64-Core Processor
|
||||
...
|
||||
Pool Info:
|
||||
Pool 1
|
||||
Segment: GLOBAL; FLAGS: FINE GRAINED
|
||||
...
|
||||
Pool 3
|
||||
Segment: GLOBAL; FLAGS: COARSE GRAINED
|
||||
...
|
||||
*******
|
||||
Agent 9
|
||||
*******
|
||||
Name: gfx90a
|
||||
...
|
||||
Pool Info:
|
||||
Pool 1
|
||||
Segment: GLOBAL; FLAGS: COARSE GRAINED
|
||||
...
|
||||
|
||||
The APIs, flags and respective memory coherence control are listed in the
|
||||
following table:
|
||||
|
||||
.. list-table:: Memory coherence control
|
||||
:widths: 25, 35, 20, 20
|
||||
:header-rows: 1
|
||||
:align: center
|
||||
|
||||
* - API
|
||||
- Flag
|
||||
- :cpp:func:`hipMemAdvise` call with argument
|
||||
- Coherence
|
||||
* - ``hipHostMalloc`` :sup:`1`
|
||||
- ``hipHostMallocDefault``
|
||||
-
|
||||
- Fine-grained
|
||||
* - ``hipHostMalloc`` :sup:`1`
|
||||
- ``hipHostMallocNonCoherent``
|
||||
-
|
||||
- Coarse-grained
|
||||
* - ``hipExtMallocWithFlags``
|
||||
- ``hipDeviceMallocDefault``
|
||||
-
|
||||
- Coarse-grained
|
||||
* - ``hipExtMallocWithFlags``
|
||||
- ``hipDeviceMallocFinegrained``
|
||||
-
|
||||
- Fine-grained
|
||||
* - ``hipMallocManaged``
|
||||
-
|
||||
-
|
||||
- Fine-grained
|
||||
* - ``hipMallocManaged``
|
||||
-
|
||||
- ``hipMemAdviseSetCoarseGrain``
|
||||
- Coarse-grained
|
||||
* - ``malloc``
|
||||
-
|
||||
-
|
||||
- Fine-grained
|
||||
* - ``malloc``
|
||||
-
|
||||
- ``hipMemAdviseSetCoarseGrain``
|
||||
- Coarse-grained
|
||||
|
||||
:sup:`1` The :cpp:func:`hipHostMalloc` memory allocation coherence mode can be
|
||||
affected by the ``HIP_HOST_COHERENT`` environment variable, if the
|
||||
``hipHostMallocCoherent``, ``hipHostMallocNonCoherent``, and
|
||||
``hipHostMallocMapped`` are unset. If neither these flags nor the
|
||||
``HIP_HOST_COHERENT`` environment variable is set, or set as 0, the host memory
|
||||
allocation is coarse-grained.
|
||||
|
||||
.. note::
|
||||
|
||||
* When ``hipHostMallocMapped`` flag is set, the allocated host memory is
|
||||
fine-grained and the ``hipHostMallocNonCoherent`` flag is ignored.
|
||||
* Setting both the ``hipHostMallocCoherent`` and
|
||||
``hipHostMallocNonCoherent`` flags leads to an illegal state.
|
||||
|
||||
Visibility of synchronization functions
|
||||
================================================================================
|
||||
|
||||
The fine-grained coherence memory is visible at the synchronization points,
|
||||
however the visibility of coarse-grained memory depends on the synchronization
|
||||
function used. The effect and visibility of various synchronization functions on
|
||||
fine- and coarse-grained memory types are listed here:
|
||||
|
||||
.. list-table:: HIP synchronize functions effect and visibility
|
||||
|
||||
* - HIP API
|
||||
- :cpp:func:`hipStreamSynchronize`
|
||||
- :cpp:func:`hipDeviceSynchronize`
|
||||
- :cpp:func:`hipEventSynchronize`
|
||||
- :cpp:func:`hipStreamWaitEvent`
|
||||
* - Synchronization effect
|
||||
- Host waits for all commands in the specified stream to complete
|
||||
- Host waits for all commands in all streams on the specified device to complete
|
||||
- Host waits for the specified event to complete
|
||||
- Stream waits for the specified event to complete
|
||||
* - Fence
|
||||
- System-scope release
|
||||
- System-scope release
|
||||
- System-scope release
|
||||
- None
|
||||
* - Fine-grained host memory visibility
|
||||
- Yes
|
||||
- Yes
|
||||
- Yes
|
||||
- Yes
|
||||
* - Coarse-grained host memory visibility
|
||||
- Yes
|
||||
- Yes
|
||||
- Depends on the used event.
|
||||
- No
|
||||
|
||||
You can control the release scope for ``hipEvents``. By default, the GPU
|
||||
performs a device-scope acquire and release operation with each recorded event.
|
||||
This makes the host and device memory visible to other commands executing on the
|
||||
same device.
|
||||
|
||||
:cpp:func:`hipEventCreateWithFlags`: You can specify a stronger system-level
|
||||
fence by creating the event with ``hipEventCreateWithFlags``:
|
||||
|
||||
* ``hipEventReleaseToSystem``: Performs a system-scope release operation when
|
||||
the event is recorded. This makes both fine-grained and coarse-grained host
|
||||
memory visible to other agents in the system, which might also involve
|
||||
heavyweight operations such as cache flushing. Fine-grained memory typically
|
||||
uses lighter-weight in-kernel synchronization mechanisms such as an atomic
|
||||
operation and thus doesn't need to use ``hipEventReleaseToSystem``.
|
||||
|
||||
* ``hipEventDisableTiming``: Events created with this flag don't record
|
||||
profiling data, which significantly improves synchronization performance.
|
||||
@@ -0,0 +1,285 @@
|
||||
.. meta::
|
||||
:description: This chapter describes the device memory of the HIP ecosystem
|
||||
ROCm software.
|
||||
:keywords: AMD, ROCm, HIP, GPU, device memory, global, constant, texture, surface, shared
|
||||
|
||||
.. _device_memory:
|
||||
|
||||
********************************************************************************
|
||||
Device memory
|
||||
********************************************************************************
|
||||
|
||||
Device memory is random access memory that is physically located on a GPU. In
|
||||
general it is memory with a bandwidth that is an order of magnitude higher
|
||||
compared to RAM available to the host. That high bandwidth is only available to
|
||||
on-device accesses, accesses from the host or other devices have to go over a
|
||||
special interface which is considerably slower, usually the PCIe bus or the AMD
|
||||
Infinity Fabric.
|
||||
|
||||
On certain architectures like APUs, the GPU and CPU share the same physical
|
||||
memory.
|
||||
|
||||
There is also a special local data share on-chip directly accessible to the
|
||||
:ref:`compute units <hardware_implementation>`, that can be used for shared
|
||||
memory.
|
||||
|
||||
The physical device memory can be used to back up several different memory
|
||||
spaces in HIP, as described in the following.
|
||||
|
||||
Global memory
|
||||
================================================================================
|
||||
|
||||
Global memory is the general read-write accessible memory visible to all threads
|
||||
on a given device. Since variables located in global memory have to be marked
|
||||
with the ``__device__`` qualifier, this memory space is also referred to as
|
||||
device memory.
|
||||
|
||||
Without explicitly copying it, it can only be accessed by the threads within a
|
||||
kernel operating on the device, however :ref:`unified_memory` can be used to
|
||||
let the runtime manage this, if desired.
|
||||
|
||||
Allocating global memory
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
This memory needs to be explicitly allocated.
|
||||
|
||||
It can be allocated from the host via the :ref:`HIP runtime memory management
|
||||
functions <memory_management_reference>` like :cpp:func:`hipMalloc`, or can be
|
||||
defined using the ``__device__`` qualifier on variables.
|
||||
|
||||
It can also be allocated within a kernel using ``malloc`` or ``new``.
|
||||
The specified amount of memory is allocated by each thread that executes the
|
||||
instructions. The recommended way to allocate the memory depends on the use
|
||||
case. If the memory is intended to be shared between the threads of a block, it
|
||||
is generally beneficial to allocate one large block of memory, due to the way
|
||||
the memory is accessed.
|
||||
|
||||
.. note::
|
||||
Memory allocated within a kernel can only be freed in kernels, not by the HIP
|
||||
runtime on the host, like :cpp:func:`hipFree`. It is also not possible to
|
||||
free device memory allocated on the host, with :cpp:func:`hipMalloc` for
|
||||
example, in a kernel.
|
||||
|
||||
|
||||
An example for how to share memory allocated within a kernel by only one thread
|
||||
is given in the following example. In case the device memory is only needed for
|
||||
communication between the threads in a single block, :ref:`shared_memory` is the
|
||||
better option, but is also limited in size.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
__global__ void kernel_memory_allocation(TYPE* pointer){
|
||||
// The pointer is stored in shared memory, so that all
|
||||
// threads of the block can access the pointer
|
||||
__shared__ int *memory;
|
||||
|
||||
size_t blockSize = blockDim.x;
|
||||
constexpr size_t elementsPerThread = 1024;
|
||||
if(threadIdx.x == 0){
|
||||
// allocate memory in one contiguous block
|
||||
memory = new int[blockDim.x * elementsPerThread];
|
||||
}
|
||||
__syncthreads();
|
||||
|
||||
// load pointer into thread-local variable to avoid
|
||||
// unnecessary accesses to shared memory
|
||||
int *localPtr = memory;
|
||||
|
||||
// work with allocated memory, e.g. initialization
|
||||
for(int i = 0; i < elementsPerThread; ++i){
|
||||
// access in a contiguous way
|
||||
localPtr[i * blockSize + threadIdx.x] = i;
|
||||
}
|
||||
|
||||
// synchronize to make sure no thread is accessing the memory before freeing
|
||||
__syncthreads();
|
||||
if(threadIdx.x == 0){
|
||||
delete[] memory;
|
||||
}
|
||||
}
|
||||
|
||||
Copying between device and host
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
When not using :ref:`unified_memory`, memory has to be explicitly copied between
|
||||
the device and the host, using the HIP runtime API.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
size_t elements = 1 << 20;
|
||||
size_t size_bytes = elements * sizeof(int);
|
||||
|
||||
// allocate host and device memory
|
||||
int *host_pointer = new int[elements];
|
||||
int *device_input, *device_result;
|
||||
HIP_CHECK(hipMalloc(&device_input, size_bytes));
|
||||
HIP_CHECK(hipMalloc(&device_result, size_bytes));
|
||||
|
||||
// copy from host to the device
|
||||
HIP_CHECK(hipMemcpy(device_input, host_pointer, size_bytes, hipMemcpyHostToDevice));
|
||||
|
||||
// Use memory on the device, i.e. execute kernels
|
||||
|
||||
// copy from device to host, to e.g. get results from the kernel
|
||||
HIP_CHECK(hipMemcpy(host_pointer, device_result, size_bytes, hipMemcpyDeviceToHost));
|
||||
|
||||
// free memory when not needed any more
|
||||
HIP_CHECK(hipFree(device_result));
|
||||
HIP_CHECK(hipFree(device_input));
|
||||
delete[] host_pointer;
|
||||
|
||||
Constant memory
|
||||
================================================================================
|
||||
|
||||
Constant memory is read-only storage visible to all threads on a given device.
|
||||
It is a limited segment backed by device memory, that takes a different caching
|
||||
route than normal device memory accesses. It needs to be set by the host before
|
||||
kernel execution.
|
||||
|
||||
In order to get the highest bandwidth from the constant memory, all threads of
|
||||
a warp have to access the same memory address. If they access different
|
||||
addresses, the accesses get serialized and the bandwidth is therefore reduced.
|
||||
|
||||
Using constant memory
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Constant memory can not be dynamically allocated, and the size has to be
|
||||
specified during compile time. If the values can not be specified during compile
|
||||
time, they have to be set by the host before the kernel, that accesses the
|
||||
constant memory, is called.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
constexpr size_t const_array_size = 32;
|
||||
__constant__ double const_array[const_array_size];
|
||||
|
||||
void set_constant_memory(double* values){
|
||||
hipMemcpyToSymbol(const_array, values, const_array_size * sizeof(double));
|
||||
}
|
||||
|
||||
__global__ void kernel_using_const_memory(double* array){
|
||||
|
||||
int warpIdx = threadIdx.x / warpSize;
|
||||
// uniform access of warps to const_array for best performance
|
||||
array[blockDim.x] *= const_array[warpIdx];
|
||||
}
|
||||
|
||||
Texture memory
|
||||
================================================================================
|
||||
|
||||
Texture memory is special read-only memory visible to all threads on a given
|
||||
device and accessible through additional APIs. Its origins come from graphics
|
||||
APIs, and provides performance benefits when accessing memory in a pattern where
|
||||
the addresses are close to each other in a 2D or 3D representation of the
|
||||
memory. It also provides additional features like filtering and addressing for
|
||||
out-of-bounds accesses, which are further explained in :ref:`texture_fetching`.
|
||||
|
||||
The original use of the texture cache was also to take pressure off the global
|
||||
memory and other caches, however on modern GPUs, that support textures, the L1
|
||||
cache and texture cache are combined, so the main purpose is to make use of the
|
||||
texture specific features.
|
||||
|
||||
To find out whether textures are supported on a device, query
|
||||
:cpp:enumerator:`hipDeviceAttributeImageSupport`.
|
||||
|
||||
Using texture memory
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Textures are more complex than just a region of memory, so their layout has to
|
||||
be specified. They are represented by ``hipTextureObject_t`` and created using
|
||||
:cpp:func:`hipCreateTextureObject`.
|
||||
|
||||
The underlying memory is a 1D, 2D or 3D ``hipArray_t``, that needs to be
|
||||
allocated using :cpp:func:`hipMallocArray`.
|
||||
|
||||
On the device side, texture objects are accessed using the ``tex1D/2D/3D``
|
||||
functions.
|
||||
|
||||
The texture management functions can be found in the :ref:`Texture management
|
||||
API reference <texture_management_reference>`
|
||||
|
||||
A full example for how to use textures can be found in the `ROCm texture
|
||||
management example <https://github.com/ROCm/rocm-examples/blob/develop/HIP-Basic/texture_management/main.hip>`_
|
||||
|
||||
Surface memory
|
||||
================================================================================
|
||||
|
||||
A read-write version of texture memory. It is created in the same way as a
|
||||
texture, but with :cpp:func:`hipCreateSurfaceObject`.
|
||||
|
||||
Since surfaces are also cached in the read-only texture cache, the changes
|
||||
written back to the surface can't be observed in the same kernel. A new kernel
|
||||
has to be launched in order to see the updated surface.
|
||||
|
||||
The corresponding functions are listed in the :ref:`Surface object API reference
|
||||
<surface_object_reference>`.
|
||||
|
||||
.. _shared_memory:
|
||||
|
||||
Shared memory
|
||||
================================================================================
|
||||
|
||||
Shared memory is read-write memory, that is only visible to the threads within a
|
||||
block. It is allocated per thread block, and needs to be either statically
|
||||
allocated at compile time, or can be dynamically allocated when launching the
|
||||
kernel, but not during kernel execution. Its general use-case is to share
|
||||
variables between the threads within a block, but can also be used as scratch
|
||||
pad memory.
|
||||
|
||||
Shared memory is not backed by the same physical memory as the other address
|
||||
spaces. It is on-chip memory local to the :ref:`compute units
|
||||
<hardware_implementation>`, providing low-latency, high-bandwidth access,
|
||||
comparable to the L1 cache. It is however limited in size, and as it is
|
||||
allocated per block, can restrict how many blocks can be scheduled to a compute
|
||||
unit concurrently, thereby potentially reducing occupancy.
|
||||
|
||||
An overview of the size of the local data share (LDS), that backs up shared
|
||||
memory, is given in the
|
||||
:doc:`GPU hardware specifications <rocm:reference/gpu-arch-specs>`.
|
||||
|
||||
Allocate shared memory
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Memory can be dynamically allocated by declaring an ``extern __shared__`` array,
|
||||
whose size can be set during kernel launch, which can then be accessed in the
|
||||
kernel.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
extern __shared__ int dynamic_shared[];
|
||||
__global__ void kernel(int array1SizeX, int array1SizeY, int array2Size){
|
||||
// at least (array1SizeX * array1SizeY + array2Size) * sizeof(int) bytes
|
||||
// dynamic shared memory need to be allocated when the kernel is launched
|
||||
int* array1 = dynamic_shared;
|
||||
// array1 is interpreted as 2D of size:
|
||||
int array1Size = array1SizeX * array1SizeY;
|
||||
|
||||
int* array2 = &(array1[array1Size]);
|
||||
|
||||
if(threadIdx.x < array1SizeX && threadIdx.y < array1SizeY){
|
||||
// access array1 with threadIdx.x + threadIdx.y * array1SizeX
|
||||
}
|
||||
if(threadIdx.x < array2Size){
|
||||
// access array2 threadIdx.x
|
||||
}
|
||||
}
|
||||
|
||||
A more in-depth example on dynamically allocated shared memory can be found in
|
||||
the `ROCm dynamic shared example
|
||||
<https://github.com/ROCm/rocm-examples/tree/develop/HIP-Basic/dynamic_shared>`_.
|
||||
|
||||
To statically allocate shared memory, just declare it in the kernel. The memory
|
||||
is allocated per block, not per thread. If the kernel requires more shared
|
||||
memory than is available to the architecture, the compilation fails.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
__global__ void kernel(){
|
||||
__shared__ int array[128];
|
||||
__shared__ double result;
|
||||
}
|
||||
|
||||
A more in-depth example on statically allocated shared memory can be found in
|
||||
the `ROCm shared memory example
|
||||
<https://github.com/ROCm/rocm-examples/tree/develop/HIP-Basic/shared_memory>`_.
|
||||
|
||||
@@ -0,0 +1,241 @@
|
||||
.. meta::
|
||||
:description: This chapter describes the texture fetching modes of the HIP ecosystem
|
||||
ROCm software.
|
||||
:keywords: AMD, ROCm, HIP, Texture, Texture Fetching
|
||||
|
||||
.. _texture_fetching:
|
||||
|
||||
********************************************************************************
|
||||
Texture fetching
|
||||
********************************************************************************
|
||||
|
||||
Textures give access to specialized hardware on GPUs that is usually used in
|
||||
graphics processing. In particular, textures use a different way of accessing
|
||||
their underlying device memory. Memory accesses to textures are routed through
|
||||
a special read-only texture cache, that is optimized for logical spatial
|
||||
locality, e.g. locality in 2D grids. This can also benefit certain algorithms
|
||||
used in GPGPU computing, when the access pattern is the same as used when
|
||||
accessing normal textures.
|
||||
|
||||
Additionally, textures can be indexed using floating-point values. This is used
|
||||
in graphics applications to interpolate between neighboring values of a texture.
|
||||
Depending on the interpolation mode the index can be in the range of ``0`` to
|
||||
``size - 1`` or ``0`` to ``1``. Textures also have a way of handling
|
||||
out-of-bounds accesses.
|
||||
|
||||
Depending on the value of the index, :ref:`texture filtering <texture_filtering>`
|
||||
or :ref:`texture addressing <texture_addressing>` is performed.
|
||||
|
||||
Here is the example texture used in this document for demonstration purposes. It
|
||||
is 2x2 texels and indexed in the [0 to 1] range.
|
||||
|
||||
.. figure:: ../../../../data/how-to/hip_runtime_api/memory_management/textures/original.png
|
||||
:width: 150
|
||||
:alt: Example texture
|
||||
:align: center
|
||||
|
||||
Texture used as example
|
||||
|
||||
In HIP textures objects are of type :cpp:struct:`hipTextureObject_t` and created
|
||||
using :cpp:func:`hipCreateTextureObject`.
|
||||
|
||||
For a full list of available texture functions see the :ref:`HIP texture API
|
||||
reference <texture_management_reference>`.
|
||||
|
||||
A code example for how to use textures can be found in the `ROCm texture
|
||||
management example <https://github.com/ROCm/rocm-examples/blob/develop/HIP-Basic/texture_management/main.hip>`_
|
||||
|
||||
.. _texture_filtering:
|
||||
|
||||
Texture filtering
|
||||
================================================================================
|
||||
|
||||
Texture filtering handles the usage of fractional indices. When the index is a
|
||||
fraction, the queried value lies between two or more texels (texture elements),
|
||||
depending on the dimensionality of the texture. The filtering method defines how
|
||||
to interpolate between these values.
|
||||
|
||||
The filter modes are specified in :cpp:enumerator:`hipTextureFilterMode`.
|
||||
|
||||
The various texture filtering methods are discussed in the following sections.
|
||||
|
||||
.. _texture_fetching_nearest:
|
||||
|
||||
Nearest point filtering
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This filter mode corresponds to ``hipFilterModePoint``.
|
||||
|
||||
In this method, the modulo of index is calculated as:
|
||||
|
||||
``tex(x) = T[floor(x)]``
|
||||
|
||||
This is also applicable for 2D and 3D variants.
|
||||
|
||||
This doesn't interpolate between neighboring values, which results in a
|
||||
pixelated look.
|
||||
|
||||
The following image shows a texture stretched to a 4x4 pixel quad but still
|
||||
indexed in the [0 to 1] range. The in-between values are the same as the values
|
||||
of the nearest texel.
|
||||
|
||||
.. figure:: ../../../../data/how-to/hip_runtime_api/memory_management/textures/nearest.png
|
||||
:width: 300
|
||||
:alt: Texture upscaled with nearest point filtering
|
||||
:align: center
|
||||
|
||||
Texture upscaled with nearest point filtering
|
||||
|
||||
.. _texture_fetching_linear:
|
||||
|
||||
Linear filtering
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This filter mode corresponds to ``hipFilterModeLinear``.
|
||||
|
||||
The linear filtering method does a linear interpolation between values. Linear
|
||||
interpolation is used to create a linear transition between two values. The
|
||||
formula used is ``(1-t)P1 + tP2`` where ``P1`` and ``P2`` are the values and
|
||||
``t`` is within the [0 to 1] range.
|
||||
|
||||
In the case of linear texture filtering the following formulas are used:
|
||||
|
||||
* For one dimensional textures: ``tex(x) = (1-α)T[i] + αT[i+1]``
|
||||
* For two dimensional textures: ``tex(x,y) = (1-α)(1-β)T[i,j] + α(1-β)T[i+1,j] + (1-α)βT[i,j+1] + αβT[i+1,j+1]``
|
||||
* For three dimensional textures: ``tex(x,y,z) = (1-α)(1-β)(1-γ)T[i,j,k] + α(1-β)(1-γ)T[i+1,j,k] + (1-α)β(1-γ)T[i,j+1,k] + αβ(1-γ)T[i+1,j+1,k] + (1-α)(1-β)γT[i,j,k+1] + α(1-β)γT[i+1,j,k+1] + (1-α)βγT[i,j+1,k+1] + αβγT[i+1,j+1,k+1]``
|
||||
|
||||
Where x, y, and, z are the floating-point indices. i, j, and, k are the integer
|
||||
indices and, α, β, and, γ values represent how far along the sampled point is on
|
||||
the three axes. These values are calculated by these formulas: ``i = floor(x')``, ``α = frac(x')``, ``x' = x - 0.5``, ``j = floor(y')``, ``β = frac(y')``, ``y' = y - 0.5``, ``k = floor(z')``, ``γ = frac(z')`` and ``z' = z - 0.5``
|
||||
|
||||
The following image shows a texture stretched out to a 4x4 pixel quad, but
|
||||
still indexed in the [0 to 1] range. The in-between values are interpolated
|
||||
between the neighboring texels.
|
||||
|
||||
.. figure:: ../../../../data/how-to/hip_runtime_api/memory_management/textures/linear.png
|
||||
:width: 300
|
||||
:alt: Texture upscaled with linear filtering
|
||||
:align: center
|
||||
|
||||
Texture upscaled with linear filtering
|
||||
|
||||
.. _texture_addressing:
|
||||
|
||||
Texture addressing
|
||||
===============================================================================
|
||||
|
||||
The texture addressing modes are specified in
|
||||
:cpp:enumerator:`hipTextureAddressMode`.
|
||||
|
||||
The texture addressing mode handles out-of-bounds accesses to the texture. This
|
||||
can be used in graphics applications to e.g. repeat a texture on a surface
|
||||
multiple times in various ways or create visible signs of out-of-bounds
|
||||
indexing.
|
||||
|
||||
The following sections describe the various texture addressing methods.
|
||||
|
||||
.. _texture_fetching_border:
|
||||
|
||||
Address mode border
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This addressing mode is set using ``hipAddressModeBorder``.
|
||||
|
||||
This addressing mode returns a border value when indexing out of bounds. The
|
||||
border value must be set before texture fetching.
|
||||
|
||||
The following image shows the texture on a 4x4 pixel quad, indexed in the
|
||||
[0 to 3] range. The out-of-bounds values are the border color, which is yellow.
|
||||
|
||||
.. figure:: ../../../../data/how-to/hip_runtime_api/memory_management/textures/border.png
|
||||
:width: 300
|
||||
:alt: Texture with yellow border color
|
||||
:align: center
|
||||
|
||||
Texture with yellow border color.
|
||||
|
||||
The purple lines are not part of the texture. They only denote the edge, where
|
||||
the addressing begins.
|
||||
|
||||
.. _texture_fetching_clamp:
|
||||
|
||||
Address mode clamp
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This addressing mode is set using ``hipAddressModeClamp``.
|
||||
|
||||
This mode clamps the index between [0 to size-1]. Due to this, when indexing
|
||||
out-of-bounds, the values on the edge of the texture repeat. The clamp mode is
|
||||
the default addressing mode.
|
||||
|
||||
The following image shows the texture on a 4x4 pixel quad, indexed in the
|
||||
[0 to 3] range. The out-of-bounds values are repeating the values at the edge of
|
||||
the texture.
|
||||
|
||||
.. figure:: ../../../../data/how-to/hip_runtime_api/memory_management/textures/clamp.png
|
||||
:width: 300
|
||||
:alt: Texture with clamp addressing
|
||||
:align: center
|
||||
|
||||
Texture with clamp addressing
|
||||
|
||||
The purple lines are not part of the texture. They only denote the edge, where
|
||||
the addressing begins.
|
||||
|
||||
.. _texture_fetching_wrap:
|
||||
|
||||
Address mode wrap
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This addressing mode is set using ``hipAddressModeWrap``.
|
||||
|
||||
Wrap mode addressing is only available for normalized texture coordinates. In
|
||||
this addressing mode, the fractional part of the index is used:
|
||||
|
||||
``tex(frac(x))``
|
||||
|
||||
This creates a repeating image effect.
|
||||
|
||||
The following image shows the texture on a 4x4 pixel quad, indexed in the
|
||||
[0 to 3] range. The out-of-bounds values are repeating the original texture.
|
||||
|
||||
.. figure:: ../../../../data/how-to/hip_runtime_api/memory_management/textures/wrap.png
|
||||
:width: 300
|
||||
:alt: Texture with wrap addressing
|
||||
:align: center
|
||||
|
||||
Texture with wrap addressing.
|
||||
|
||||
The purple lines are not part of the texture. They only denote the edge, where
|
||||
the addressing begins.
|
||||
|
||||
.. _texture_fetching_mirror:
|
||||
|
||||
Address mode mirror
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This addressing mode is set using ``hipAddressModeMirror``.
|
||||
|
||||
Similar to the wrap mode the mirror mode is only available for normalized
|
||||
texture coordinates and also creates a repeating image, but mirroring the
|
||||
neighboring instances.
|
||||
|
||||
The formula is the following:
|
||||
|
||||
``tex(frac(x))``, if ``floor(x)`` is even,
|
||||
|
||||
``tex(1 - frac(x))``, if ``floor(x)`` is odd.
|
||||
|
||||
The following image shows the texture on a 4x4 pixel quad, indexed in The
|
||||
[0 to 3] range. The out-of-bounds values are repeating the original texture, but
|
||||
mirrored.
|
||||
|
||||
.. figure:: ../../../../data/how-to/hip_runtime_api/memory_management/textures/mirror.png
|
||||
:width: 300
|
||||
:alt: Texture with mirror addressing
|
||||
:align: center
|
||||
|
||||
Texture with mirror addressing
|
||||
|
||||
The purple lines are not part of the texture. They only denote the edge, where
|
||||
the addressing begins.
|
||||
@@ -0,0 +1,239 @@
|
||||
.. meta::
|
||||
:description: Host memory of the HIP ecosystem
|
||||
:keywords: AMD, ROCm, HIP, host memory
|
||||
|
||||
.. _host_memory:
|
||||
|
||||
********************************************************************************
|
||||
Host memory
|
||||
********************************************************************************
|
||||
|
||||
Host memory is the "normal" memory residing in the host RAM and allocated by C
|
||||
or C++. Host memory can be allocated in two different ways:
|
||||
|
||||
* Pageable memory
|
||||
|
||||
* Pinned memory
|
||||
|
||||
The following figure explains how data is transferred in pageable and pinned
|
||||
memory.
|
||||
|
||||
.. figure:: ../../../data/how-to/hip_runtime_api/memory_management/pageable_pinned.svg
|
||||
|
||||
The pageable and pinned memory allow you to exercise direct control over
|
||||
memory operations, which is known as explicit memory management. When using the
|
||||
unified memory, you get a simplified memory model with less control over
|
||||
low level memory operations.
|
||||
|
||||
The difference in memory transfers between explicit and unified memory
|
||||
management is highlighted in the following figure:
|
||||
|
||||
.. figure:: ../../../data/how-to/hip_runtime_api/memory_management/unified_memory/um.svg
|
||||
|
||||
For more details on unified memory management, see :doc:`/how-to/hip_runtime_api/memory_management/unified_memory`.
|
||||
|
||||
.. _pageable_host_memory:
|
||||
|
||||
Pageable memory
|
||||
================================================================================
|
||||
|
||||
Pageable memory exists on memory blocks known as "pages" that can be migrated to
|
||||
other memory storage. For example, migrating memory between CPU sockets on a
|
||||
motherboard or in a system whose RAM runs out of space and starts dumping pages
|
||||
into the swap partition of the hard drive.
|
||||
|
||||
Pageable memory is usually allocated with a call to ``malloc`` or ``new`` in a
|
||||
C++ application.
|
||||
|
||||
**Example:** Using pageable host memory in HIP
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <iostream>
|
||||
|
||||
#define HIP_CHECK(expression) \
|
||||
{ \
|
||||
const hipError_t status = expression; \
|
||||
if(status != hipSuccess){ \
|
||||
std::cerr << "HIP error " \
|
||||
<< status << ": " \
|
||||
<< hipGetErrorString(status) \
|
||||
<< " at " << __FILE__ << ":" \
|
||||
<< __LINE__ << std::endl; \
|
||||
} \
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
const int element_number = 100;
|
||||
|
||||
int *host_input, *host_output;
|
||||
// Host allocation
|
||||
host_input = new int[element_number];
|
||||
host_output = new int[element_number];
|
||||
|
||||
// Host data preparation
|
||||
for (int i = 0; i < element_number; i++) {
|
||||
host_input[i] = i;
|
||||
}
|
||||
memset(host_output, 0, element_number * sizeof(int));
|
||||
|
||||
int *device_input, *device_output;
|
||||
|
||||
// Device allocation
|
||||
HIP_CHECK(hipMalloc((int **)&device_input, element_number * sizeof(int)));
|
||||
HIP_CHECK(hipMalloc((int **)&device_output, element_number * sizeof(int)));
|
||||
|
||||
// Device data preparation
|
||||
HIP_CHECK(hipMemcpy(device_input, host_input, element_number * sizeof(int), hipMemcpyHostToDevice));
|
||||
HIP_CHECK(hipMemset(device_output, 0, element_number * sizeof(int)));
|
||||
|
||||
// Run the kernel
|
||||
// ...
|
||||
|
||||
HIP_CHECK(hipMemcpy(device_input, host_input, element_number * sizeof(int), hipMemcpyHostToDevice));
|
||||
|
||||
// Free host memory
|
||||
delete[] host_input;
|
||||
delete[] host_output;
|
||||
|
||||
// Free device memory
|
||||
HIP_CHECK(hipFree(device_input));
|
||||
HIP_CHECK(hipFree(device_output));
|
||||
}
|
||||
|
||||
.. note::
|
||||
|
||||
:cpp:func:`hipMalloc` and :cpp:func:`hipFree` are blocking calls. However, HIP
|
||||
also provides non-blocking versions :cpp:func:`hipMallocAsync` and
|
||||
:cpp:func:`hipFreeAsync`, which require a stream as an additional argument.
|
||||
|
||||
.. _pinned_host_memory:
|
||||
|
||||
Pinned memory
|
||||
================================================================================
|
||||
|
||||
Pinned memory or page-locked memory is stored in pages that are locked in
|
||||
specific sectors in RAM and can't be migrated. The pointer can be used on both
|
||||
host and device. Accessing host-resident pinned memory in device kernels is
|
||||
generally not recommended for performance, as it can force the data to traverse
|
||||
the host-device interconnect such as PCIe, which is much slower than the
|
||||
on-device bandwidth.
|
||||
|
||||
The advantage of pinned memory is the improved transfer time between host and
|
||||
device. For transfer operations, such as :cpp:func:`hipMemcpy` or :cpp:func:`hipMemcpyAsync`,
|
||||
using pinned memory instead of pageable memory on the host can lead to a three times
|
||||
improvement in bandwidth.
|
||||
|
||||
The disadvantage of pinned memory is the reduced availability of RAM for other
|
||||
processes, which can negatively impact the overall performance of the host.
|
||||
|
||||
**Example:** Using pinned memory in HIP
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <iostream>
|
||||
|
||||
#define HIP_CHECK(expression) \
|
||||
{ \
|
||||
const hipError_t status = expression; \
|
||||
if(status != hipSuccess){ \
|
||||
std::cerr << "HIP error " \
|
||||
<< status << ": " \
|
||||
<< hipGetErrorString(status) \
|
||||
<< " at " << __FILE__ << ":" \
|
||||
<< __LINE__ << std::endl; \
|
||||
} \
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
const int element_number = 100;
|
||||
|
||||
int *host_input, *host_output;
|
||||
// Host allocation
|
||||
HIP_CHECK(hipHostMalloc((int **)&host_input, element_number * sizeof(int)));
|
||||
HIP_CHECK(hipHostMalloc((int **)&host_output, element_number * sizeof(int)));
|
||||
|
||||
// Host data preparation
|
||||
for (int i = 0; i < element_number; i++) {
|
||||
host_input[i] = i;
|
||||
}
|
||||
memset(host_output, 0, element_number * sizeof(int));
|
||||
|
||||
int *device_input, *device_output;
|
||||
|
||||
// Device allocation
|
||||
HIP_CHECK(hipMalloc((int **)&device_input, element_number * sizeof(int)));
|
||||
HIP_CHECK(hipMalloc((int **)&device_output, element_number * sizeof(int)));
|
||||
|
||||
// Device data preparation
|
||||
HIP_CHECK(hipMemcpy(device_input, host_input, element_number * sizeof(int), hipMemcpyHostToDevice));
|
||||
HIP_CHECK(hipMemset(device_output, 0, element_number * sizeof(int)));
|
||||
|
||||
// Run the kernel
|
||||
// ...
|
||||
|
||||
HIP_CHECK(hipMemcpy(device_input, host_input, element_number * sizeof(int), hipMemcpyHostToDevice));
|
||||
|
||||
// Free host memory
|
||||
delete[] host_input;
|
||||
delete[] host_output;
|
||||
|
||||
// Free device memory
|
||||
HIP_CHECK(hipFree(device_input));
|
||||
HIP_CHECK(hipFree(device_output));
|
||||
}
|
||||
|
||||
.. _memory_allocation_flags:
|
||||
|
||||
Memory allocation flags for pinned memory
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
The memory allocation for pinned memory can be controlled using ``hipHostMalloc`` flags:
|
||||
|
||||
* ``hipHostMallocPortable``: The memory allocation is not restricted to the
|
||||
context making the allocation.
|
||||
|
||||
* ``hipHostMallocMapped``: The memory is allocated into the address space for
|
||||
the current device and the device pointer can be obtained with
|
||||
:cpp:func:`hipHostGetDevicePointer`.
|
||||
|
||||
* ``hipHostMallocNumaUser``: The host memory allocation follows Numa policy
|
||||
specified by the user. Target of Numa policy is to select a CPU that is
|
||||
closest to each GPU. Numa distance is the distance between GPU and CPU
|
||||
devices.
|
||||
|
||||
* ``hipHostMallocWriteCombined``: The memory is allocated as write-combined.
|
||||
Although lacking read efficiency by most CPUs, write-combined allocation might
|
||||
be transferred faster across the PCIe bus on some system configurations. It's
|
||||
a good option for data transfer from host to device via mapped pinned memory.
|
||||
|
||||
* ``hipHostMallocCoherent``: Fine-grained memory is allocated. Overrides
|
||||
``HIP_HOST_COHERENT`` environment variable for specific allocation. For
|
||||
details, see :ref:`coherence_control`.
|
||||
|
||||
* ``hipHostMallocNonCoherent``: Coarse-grained memory is allocated. Overrides
|
||||
``HIP_HOST_COHERENT`` environment variable for specific allocation. For
|
||||
details, see :ref:`coherence_control`.
|
||||
|
||||
All allocation flags are independent and can be set in any combination. The only
|
||||
exception is setting ``hipHostMallocCoherent`` and ``hipHostMallocNonCoherent``
|
||||
together, which leads to an illegal state. An example of a valid flag
|
||||
combination is calling :cpp:func:`hipHostMalloc` with both
|
||||
``hipHostMallocPortable`` and ``hipHostMallocMapped`` flags set. Both the flags
|
||||
use the same model and differentiate only between how the surrounding code uses
|
||||
the host memory.
|
||||
|
||||
.. note::
|
||||
|
||||
By default, each GPU selects a Numa CPU node with the least Numa distance
|
||||
between them. This implies that the host memory is automatically allocated on
|
||||
the closest memory pool of the current GPU device's Numa node. Using
|
||||
:cpp:func:`hipSetDevice` API to set a different GPU increases the Numa
|
||||
distance but still allows you to access the host allocation.
|
||||
|
||||
Numa policy is implemented on Linux and is under development on Microsoft
|
||||
Windows.
|
||||
@@ -0,0 +1,580 @@
|
||||
.. meta::
|
||||
:description:
|
||||
:keywords: stream, memory allocation, SOMA, stream ordered memory allocator
|
||||
|
||||
.. _stream_ordered_memory_allocator_how-to:
|
||||
|
||||
*******************************************************************************
|
||||
Stream Ordered Memory Allocator
|
||||
*******************************************************************************
|
||||
|
||||
The Stream Ordered Memory Allocator (SOMA) is part of the HIP runtime API. SOMA provides an asynchronous memory allocation mechanism with stream-ordering semantics. You can use SOMA to allocate and free memory in stream order, which ensures that all asynchronous accesses occur between the stream executions of allocation and deallocation. Compliance with stream order prevents use-before-allocation or use-after-free errors, which helps to avoid an undefined behavior.
|
||||
|
||||
Advantages of SOMA:
|
||||
|
||||
- Efficient reuse: Enables efficient memory reuse across streams, which reduces unnecessary allocation overhead.
|
||||
- Fine-grained control: Allows you to set attributes and control caching behavior for memory pools.
|
||||
- Inter-process sharing: Enables secure sharing of allocations between processes.
|
||||
- Optimizations: Allows driver to optimize based on its awareness of SOMA and other stream management APIs.
|
||||
|
||||
Disadvantages of SOMA:
|
||||
|
||||
- Temporal constraints: Requires you to adhere strictly to stream order to avoid errors.
|
||||
- Complexity: Involves memory management in stream order, which can be intricate.
|
||||
- Learning curve: Requires you to put additional efforts to understand and utilize SOMA effectively.
|
||||
|
||||
Using SOMA
|
||||
=====================================
|
||||
|
||||
You can allocate memory using ``hipMallocAsync()`` with stream-ordered
|
||||
semantics. This restricts the asynchronous access to the memory between the stream executions of the allocation and deallocation. Accessing
|
||||
memory if the compliant memory accesses won't overlap
|
||||
temporally. ``hipFreeAsync()`` frees memory from the pool with stream-ordered
|
||||
semantics.
|
||||
|
||||
Here is how to use stream ordered memory allocation:
|
||||
|
||||
.. tab-set::
|
||||
.. tab-item:: Stream Ordered Memory Allocation
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <iostream>
|
||||
#include <hip/hip_runtime.h>
|
||||
|
||||
// Kernel to perform some computation on allocated memory.
|
||||
__global__ void myKernel(int* data, size_t numElements) {
|
||||
int tid = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
if (tid < numElements) {
|
||||
data[tid] = tid * 2;
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
// Initialize HIP.
|
||||
hipInit(0);
|
||||
|
||||
// Stream 0.
|
||||
constexpr hipStream_t streamId = 0;
|
||||
|
||||
// Allocate memory with stream ordered semantics.
|
||||
constexpr size_t numElements = 1024;
|
||||
int* devData;
|
||||
hipMallocAsync(&devData, numElements * sizeof(*devData), streamId);
|
||||
|
||||
// Launch the kernel to perform computation.
|
||||
dim3 blockSize(256);
|
||||
dim3 gridSize((numElements + blockSize.x - 1) / blockSize.x);
|
||||
myKernel<<<gridSize, blockSize>>>(devData, numElements);
|
||||
|
||||
// Copy data back to host.
|
||||
int* hostData = new int[numElements];
|
||||
hipMemcpy(hostData, devData, numElements * sizeof(*devData), hipMemcpyDeviceToHost);
|
||||
|
||||
// Print the array.
|
||||
for (size_t i = 0; i < numElements; ++i) {
|
||||
std::cout << "Element " << i << ": " << hostData[i] << std::endl;
|
||||
}
|
||||
|
||||
// Free memory with stream ordered semantics.
|
||||
hipFreeAsync(devData, streamId);
|
||||
delete[] hostData;
|
||||
|
||||
// Synchronize to ensure completion.
|
||||
hipDeviceSynchronize();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
.. tab-item:: Ordinary Allocation
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <iostream>
|
||||
#include <hip/hip_runtime.h>
|
||||
|
||||
// Kernel to perform some computation on allocated memory.
|
||||
__global__ void myKernel(int* data, size_t numElements) {
|
||||
int tid = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
if (tid < numElements) {
|
||||
data[tid] = tid * 2;
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
// Initialize HIP.
|
||||
hipInit(0);
|
||||
|
||||
// Allocate memory.
|
||||
constexpr size_t numElements = 1024;
|
||||
int* devData;
|
||||
hipMalloc(&devData, numElements * sizeof(*devData));
|
||||
|
||||
// Launch the kernel to perform computation.
|
||||
dim3 blockSize(256);
|
||||
dim3 gridSize((numElements + blockSize.x - 1) / blockSize.x);
|
||||
myKernel<<<gridSize, blockSize>>>(devData, numElements);
|
||||
|
||||
// Copy data back to host.
|
||||
int* hostData = new int[numElements];
|
||||
hipMemcpy(hostData, devData, numElements * sizeof(*devData), hipMemcpyDeviceToHost);
|
||||
|
||||
// Print the array.
|
||||
for (size_t i = 0; i < numElements; ++i) {
|
||||
std::cout << "Element " << i << ": " << hostData[i] << std::endl;
|
||||
}
|
||||
|
||||
// Free memory.
|
||||
hipFree(devData);
|
||||
delete[] hostData;
|
||||
|
||||
// Synchronize to ensure completion.
|
||||
hipDeviceSynchronize();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
For more details, see :ref:`stream_ordered_memory_allocator_reference`.
|
||||
|
||||
Memory pools
|
||||
============
|
||||
|
||||
Memory pools provide a way to manage memory with stream-ordered behavior while ensuring proper synchronization and avoiding memory access errors. Division of a single memory system into separate pools facilitates querying the access path properties for each partition. Memory pools are used for host memory, device memory, and unified memory.
|
||||
|
||||
Set pools
|
||||
---------
|
||||
|
||||
The ``hipMallocAsync()`` function uses the current memory pool and also provides the opportunity to create and access different pools using ``hipMemPoolCreate()`` and ``hipMallocFromPoolAsync()`` functions respectively.
|
||||
|
||||
Unlike NVIDIA CUDA, where stream-ordered memory allocation can be implicit, ROCm HIP is explicit. This requires managing memory allocation for each stream in HIP while ensuring precise control over memory usage and synchronization.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <iostream>
|
||||
#include <hip/hip_runtime.h>
|
||||
|
||||
// Kernel to perform some computation on allocated memory.
|
||||
__global__ void myKernel(int* data, size_t numElements) {
|
||||
int tid = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
if (tid < numElements) {
|
||||
data[tid] = tid * 2;
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
// Create a stream.
|
||||
hipStream_t stream;
|
||||
hipStreamCreate(&stream);
|
||||
|
||||
// Create a memory pool with default properties.
|
||||
hipMemPoolProps poolProps = {};
|
||||
poolProps.allocType = hipMemAllocationTypePinned;
|
||||
poolProps.handleTypes = hipMemHandleTypePosixFileDescriptor;
|
||||
poolProps.location.type = hipMemLocationTypeDevice;
|
||||
poolProps.location.id = 0; // Assuming device 0.
|
||||
|
||||
hipMemPool_t memPool;
|
||||
hipMemPoolCreate(&memPool, &poolProps);
|
||||
|
||||
// Allocate memory from the pool asynchronously.
|
||||
constexpr size_t numElements = 1024;
|
||||
int* devData = nullptr;
|
||||
hipMallocFromPoolAsync(&devData, numElements * sizeof(*devData), memPool, stream);
|
||||
|
||||
// Define grid and block sizes.
|
||||
dim3 blockSize(256);
|
||||
dim3 gridSize((numElements + blockSize.x - 1) / blockSize.x);
|
||||
|
||||
// Launch the kernel to perform computation.
|
||||
myKernel<<<gridSize, blockSize, 0, stream>>>(devData, numElements);
|
||||
|
||||
// Synchronize the stream.
|
||||
hipStreamSynchronize(stream);
|
||||
|
||||
// Copy data back to host.
|
||||
int* hostData = new int[numElements];
|
||||
hipMemcpy(hostData, devData, numElements * sizeof(*devData), hipMemcpyDeviceToHost);
|
||||
|
||||
// Print the array.
|
||||
for (size_t i = 0; i < numElements; ++i) {
|
||||
std::cout << "Element " << i << ": " << hostData[i] << std::endl;
|
||||
}
|
||||
|
||||
// Free the allocated memory.
|
||||
hipFreeAsync(devData, stream);
|
||||
|
||||
// Synchronize the stream again to ensure all operations are complete.
|
||||
hipStreamSynchronize(stream);
|
||||
|
||||
// Destroy the memory pool and stream.
|
||||
hipMemPoolDestroy(memPool);
|
||||
hipStreamDestroy(stream);
|
||||
|
||||
// Free host memory.
|
||||
delete[] hostData;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Trim pools
|
||||
----------
|
||||
|
||||
The memory allocator allows you to allocate and free memory in stream order. To control memory usage, set the release threshold attribute using ``hipMemPoolAttrReleaseThreshold``. This threshold specifies the amount of reserved memory in bytes to hold onto.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
uint64_t threshold = UINT64_MAX;
|
||||
hipMemPoolSetAttribute(memPool, hipMemPoolAttrReleaseThreshold, &threshold);
|
||||
|
||||
When the amount of memory held in the memory pool exceeds the threshold, the allocator tries to release memory back to the operating system during the next call to stream, event, or context synchronization.
|
||||
|
||||
To improve performance, it is a good practice to adjust the memory pool size using ``hipMemPoolTrimTo()``. It helps to reclaim memory from an excessive memory pool, which optimizes memory usage for your application.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
hipMemPool_t memPool;
|
||||
hipDevice_t device = 0; // Specify the device index.
|
||||
|
||||
// Initialize the device.
|
||||
hipSetDevice(device);
|
||||
|
||||
// Get the default memory pool for the device.
|
||||
hipDeviceGetDefaultMemPool(&memPool, device);
|
||||
|
||||
// Allocate memory from the pool (e.g., 1 MB).
|
||||
size_t allocSize = 1 * 1024 * 1024;
|
||||
void* ptr;
|
||||
hipMalloc(&ptr, allocSize);
|
||||
|
||||
// Free the allocated memory.
|
||||
hipFree(ptr);
|
||||
|
||||
// Trim the memory pool to a specific size (e.g., 512 KB).
|
||||
size_t newSize = 512 * 1024;
|
||||
hipMemPoolTrimTo(memPool, newSize);
|
||||
|
||||
// Clean up.
|
||||
hipMemPoolDestroy(memPool);
|
||||
|
||||
std::cout << "Memory pool trimmed to " << newSize << " bytes." << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Resource usage statistics
|
||||
-------------------------
|
||||
|
||||
Resource usage statistics help in optimization. Here is the list of pool attributes used to query memory usage:
|
||||
|
||||
- ``hipMemPoolAttrReservedMemCurrent``: Returns the total physical GPU memory currently held in the pool.
|
||||
- ``hipMemPoolAttrUsedMemCurrent``: Returns the total size of all the memory allocated from the pool.
|
||||
- ``hipMemPoolAttrReservedMemHigh``: Returns the total physical GPU memory held in the pool since the last reset.
|
||||
- ``hipMemPoolAttrUsedMemHigh``: Returns the total size of all the memory allocated from the pool since the last reset.
|
||||
|
||||
To reset these attributes to the current value, use ``hipMemPoolSetAttribute()``.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <iostream>
|
||||
#include <hip/hip_runtime.h>
|
||||
|
||||
// Sample helper functions for getting the usage statistics in bulk.
|
||||
struct usageStatistics {
|
||||
uint64_t reservedMemCurrent;
|
||||
uint64_t reservedMemHigh;
|
||||
uint64_t usedMemCurrent;
|
||||
uint64_t usedMemHigh;
|
||||
};
|
||||
|
||||
void getUsageStatistics(hipMemPool_t memPool, struct usageStatistics *statistics) {
|
||||
hipMemPoolGetAttribute(memPool, hipMemPoolAttrReservedMemCurrent, &statistics->reservedMemCurrent);
|
||||
hipMemPoolGetAttribute(memPool, hipMemPoolAttrReservedMemHigh, &statistics->reservedMemHigh);
|
||||
hipMemPoolGetAttribute(memPool, hipMemPoolAttrUsedMemCurrent, &statistics->usedMemCurrent);
|
||||
hipMemPoolGetAttribute(memPool, hipMemPoolAttrUsedMemHigh, &statistics->usedMemHigh);
|
||||
}
|
||||
|
||||
// Resetting the watermarks resets them to the current value.
|
||||
void resetStatistics(hipMemPool_t memPool) {
|
||||
uint64_t value = 0;
|
||||
hipMemPoolSetAttribute(memPool, hipMemPoolAttrReservedMemHigh, &value);
|
||||
hipMemPoolSetAttribute(memPool, hipMemPoolAttrUsedMemHigh, &value);
|
||||
}
|
||||
|
||||
int main() {
|
||||
hipMemPool_t memPool;
|
||||
hipDevice_t device = 0; // Specify the device index.
|
||||
|
||||
// Initialize the device.
|
||||
hipSetDevice(device);
|
||||
|
||||
// Get the default memory pool for the device.
|
||||
hipDeviceGetDefaultMemPool(&memPool, device);
|
||||
|
||||
// Allocate memory from the pool (e.g., 1 MB).
|
||||
size_t allocSize = 1 * 1024 * 1024;
|
||||
void* ptr;
|
||||
hipMalloc(&ptr, allocSize);
|
||||
|
||||
// Free the allocated memory.
|
||||
hipFree(ptr);
|
||||
|
||||
// Trim the memory pool to a specific size (e.g., 512 KB).
|
||||
size_t newSize = 512 * 1024;
|
||||
hipMemPoolTrimTo(memPool, newSize);
|
||||
|
||||
// Get and print usage statistics before resetting.
|
||||
usageStatistics statsBefore;
|
||||
getUsageStatistics(memPool, &statsBefore);
|
||||
std::cout << "Before resetting statistics:" << std::endl;
|
||||
std::cout << "Reserved Memory Current: " << statsBefore.reservedMemCurrent << " bytes" << std::endl;
|
||||
std::cout << "Reserved Memory High: " << statsBefore.reservedMemHigh << " bytes" << std::endl;
|
||||
std::cout << "Used Memory Current: " << statsBefore.usedMemCurrent << " bytes" << std::endl;
|
||||
std::cout << "Used Memory High: " << statsBefore.usedMemHigh << " bytes" << std::endl;
|
||||
|
||||
// Reset the statistics.
|
||||
resetStatistics(memPool);
|
||||
|
||||
// Get and print usage statistics after resetting.
|
||||
usageStatistics statsAfter;
|
||||
getUsageStatistics(memPool, &statsAfter);
|
||||
std::cout << "After resetting statistics:" << std::endl;
|
||||
std::cout << "Reserved Memory Current: " << statsAfter.reservedMemCurrent << " bytes" << std::endl;
|
||||
std::cout << "Reserved Memory High: " << statsAfter.reservedMemHigh << " bytes" << std::endl;
|
||||
std::cout << "Used Memory Current: " << statsAfter.usedMemCurrent << " bytes" << std::endl;
|
||||
std::cout << "Used Memory High: " << statsAfter.usedMemHigh << " bytes" << std::endl;
|
||||
|
||||
// Clean up.
|
||||
hipMemPoolDestroy(memPool);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Memory reuse policies
|
||||
---------------------
|
||||
|
||||
The allocator might reallocate memory as long as the compliant memory accesses will not to overlap temporally. To optimize the memory usage, disable or enable the following memory pool reuse policy attribute flags:
|
||||
|
||||
- ``hipMemPoolReuseFollowEventDependencies``: Checks event dependencies before allocating additional GPU memory.
|
||||
- ``hipMemPoolReuseAllowOpportunistic``: Checks freed allocations to determine if the stream order semantic indicated by the free operation has been met.
|
||||
- ``hipMemPoolReuseAllowInternalDependencies``: Manages reuse based on internal dependencies in runtime. If the driver fails to allocate and map additional physical memory, it searches for memory waiting for another stream's progress and reuses it.
|
||||
|
||||
Device accessibility for multi-GPU support
|
||||
------------------------------------------
|
||||
|
||||
Allocations are initially accessible from the device where they reside.
|
||||
|
||||
Interprocess memory handling
|
||||
=============================
|
||||
|
||||
Interprocess capable (IPC) memory pools facilitate efficient and secure sharing of GPU memory between processes.
|
||||
|
||||
To achieve interprocess memory sharing, you can use either :ref:`device pointer <device-pointer>` or :ref:`shareable handle <shareable-handle>`. Both provide allocator (export) and consumer (import) interfaces.
|
||||
|
||||
.. _device-pointer:
|
||||
|
||||
Device pointer
|
||||
--------------
|
||||
|
||||
To export data to share a memory pool pointer directly between processes, use ``hipMemPoolExportPointer()``. It allows you to share a memory allocation with another process.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
int main() {
|
||||
// Allocate memory.
|
||||
void* devPtr;
|
||||
hipMalloc(&devPtr, sizeof(int));
|
||||
|
||||
// Export the memory pool pointer.
|
||||
hipMemPoolPtrExportData exportData;
|
||||
hipError_t result = hipMemPoolExportPointer(&exportData, devPtr);
|
||||
if (result != hipSuccess) {
|
||||
std::cerr << "Error exporting memory pool pointer: " << hipGetErrorString(result) << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create a named pipe (FIFO).
|
||||
const char* fifoPath = "/tmp/myfifo"; // Change this to a unique path.
|
||||
mkfifo(fifoPath, 0666);
|
||||
|
||||
// Write the exported data to the named pipe.
|
||||
std::ofstream fifoStream(fifoPath, std::ios::out | std::ios::binary);
|
||||
fifoStream.write(reinterpret_cast<char*>(&exportData), sizeof(hipMemPoolPtrExportData));
|
||||
fifoStream.close();
|
||||
|
||||
// Clean up.
|
||||
hipFree(devPtr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
To import a memory pool pointer directly from another process, use ``hipMemPoolImportPointer()``.
|
||||
|
||||
Here is how to read the pool exported in the preceding example:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <hip/hip_runtime.h>
|
||||
|
||||
int main() {
|
||||
// Considering that you have exported the memory pool pointer already.
|
||||
// Now, let's simulate reading the exported data from a named pipe (FIFO).
|
||||
const char* fifoPath = "/tmp/myfifo"; // Change this to a unique path.
|
||||
std::ifstream fifoStream(fifoPath, std::ios::in | std::ios::binary);
|
||||
|
||||
if (!fifoStream.is_open()) {
|
||||
std::cerr << "Error opening FIFO file: " << fifoPath << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Read the exported data.
|
||||
hipMemPoolPtrExportData importData;
|
||||
fifoStream.read(reinterpret_cast<char*>(&importData), sizeof(hipMemPoolPtrExportData));
|
||||
fifoStream.close();
|
||||
|
||||
if (fifoStream.fail()) {
|
||||
std::cerr << "Error reading from FIFO file." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create a memory pool with default properties.
|
||||
hipMemPoolProps poolProps = {};
|
||||
poolProps.allocType = hipMemAllocationTypePinned;
|
||||
poolProps.handleTypes = hipMemHandleTypePosixFileDescriptor;
|
||||
poolProps.location.type = hipMemLocationTypeDevice;
|
||||
poolProps.location.id = 0; // Assuming device 0.
|
||||
|
||||
hipMemPool_t memPool;
|
||||
hipMemPoolCreate(&memPool, &poolProps);
|
||||
|
||||
// Import the memory pool pointer.
|
||||
void* importedDevPtr;
|
||||
hipError_t result = hipMemPoolImportPointer(&importedDevPtr, memPool, &importData);
|
||||
if (result != hipSuccess) {
|
||||
std::cerr << "Error imported memory pool pointer: " << hipGetErrorString(result) << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Now you can use the importedDevPtr for your computations.
|
||||
|
||||
// Clean up (free the memory).
|
||||
hipFree(importedDevPtr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
.. _shareable-handle:
|
||||
|
||||
Shareable handle
|
||||
----------------
|
||||
|
||||
To export a memory pool pointer to a shareable handle, use ``hipMemPoolExportToSharedHandle()``. This handle could be a file descriptor or a handle obtained from another process. The exported handle contains information about the memory pool, such as size, location, and other relevant details.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
int main() {
|
||||
// Create a memory pool with default properties.
|
||||
hipMemPoolProps poolProps = {};
|
||||
poolProps.allocType = hipMemAllocationTypePinned;
|
||||
poolProps.handleTypes = hipMemHandleTypePosixFileDescriptor;
|
||||
poolProps.location.type = hipMemLocationTypeDevice;
|
||||
poolProps.location.id = 0; // Assuming device 0.
|
||||
|
||||
hipMemPool_t memPool;
|
||||
hipError_t poolResult = hipMemPoolCreate(&memPool, &poolProps);
|
||||
if (poolResult != hipSuccess) {
|
||||
std::cerr << "Error creating memory pool: " << hipGetErrorString(poolResult) << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Allocate memory from the memory pool.
|
||||
void* devPtr;
|
||||
hipMallocFromPoolAsync(&devPtr, sizeof(int), memPool, 0);
|
||||
|
||||
// Export the memory pool pointer.
|
||||
int descriptor;
|
||||
hipError_t result = hipMemPoolExportToShareableHandle(&descriptor, memPool, hipMemHandleTypePosixFileDescriptor, 0);
|
||||
if (result != hipSuccess) {
|
||||
std::cerr << "Error exporting memory pool pointer: " << hipGetErrorString(result) << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create a named pipe (FIFO).
|
||||
const char* fifoPath = "/tmp/myfifo"; // Change this to a unique path.
|
||||
mkfifo(fifoPath, 0666);
|
||||
|
||||
// Write the exported data to the named pipe.
|
||||
std::ofstream fifoStream(fifoPath, std::ios::out | std::ios::binary);
|
||||
fifoStream.write(reinterpret_cast<char*>(&descriptor), sizeof(int));
|
||||
fifoStream.close();
|
||||
|
||||
// Clean up.
|
||||
hipFree(devPtr);
|
||||
hipMemPoolDestroy(memPool);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
To import and restore a memory pool pointer from a shareable handle, which could be a file descriptor or a handle obtained from another process, use ``hipMemPoolImportFromShareableHandle()``. The exported shareable handle data contains information about the memory pool, including its size, location, and other relevant details. Importing the handle provides a valid memory pointer to the same memory, which allows you to share memory across different contexts.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <hip/hip_runtime.h>
|
||||
|
||||
int main() {
|
||||
// Considering that you have exported the memory pool pointer already.
|
||||
// Now, let's simulate reading the exported data from a named pipe (FIFO).
|
||||
const char* fifoPath = "/tmp/myfifo"; // Change this to a unique path
|
||||
std::ifstream fifoStream(fifoPath, std::ios::in | std::ios::binary);
|
||||
|
||||
if (!fifoStream.is_open()) {
|
||||
std::cerr << "Error opening FIFO file: " << fifoPath << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Read the exported data.
|
||||
int descriptor;
|
||||
fifoStream.read(reinterpret_cast<char*>(&descriptor), sizeof(int));
|
||||
fifoStream.close();
|
||||
|
||||
if (fifoStream.fail()) {
|
||||
std::cerr << "Error reading from FIFO file." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Import the memory pool.
|
||||
hipMemPool_t memPool;
|
||||
hipError_t result = hipMemPoolImportFromShareableHandle(&memPool, &descriptor, hipMemHandleTypePosixFileDescriptor, 0);
|
||||
if (result != hipSuccess) {
|
||||
std::cerr << "Error importing memory pool: " << hipGetErrorString(result) << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Allocate memory from the imported memory pool.
|
||||
void* importedDevPtr;
|
||||
hipMallocFromPoolAsync(&importedDevPtr, sizeof(int), memPool, 0);
|
||||
|
||||
// Now you can use the importedDevPtr for your computations.
|
||||
|
||||
// Clean up (free the memory).
|
||||
hipFree(importedDevPtr);
|
||||
hipMemPoolDestroy(memPool);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,738 @@
|
||||
.. meta::
|
||||
:description: This chapter describes Unified Memory and shows
|
||||
how to use it in AMD HIP.
|
||||
:keywords: AMD, ROCm, HIP, CUDA, unified memory, unified, memory
|
||||
|
||||
.. _unified_memory:
|
||||
|
||||
*******************************************************************************
|
||||
Unified memory management
|
||||
*******************************************************************************
|
||||
|
||||
In conventional architectures CPUs and attached devices have their own memory
|
||||
space and dedicated physical memory backing it up, e.g. normal RAM for CPUs and
|
||||
VRAM on GPUs. This way each device can have physical memory optimized for its
|
||||
use case. GPUs usually have specialized memory whose bandwidth is a
|
||||
magnitude higher than the RAM attached to CPUs.
|
||||
|
||||
While providing exceptional performance, this setup typically requires explicit
|
||||
memory management, as memory needs to be allocated, copied and freed on the used
|
||||
devices and on the host. Additionally, this makes using more than the physically
|
||||
available memory on the devices complicated.
|
||||
|
||||
Modern GPUs circumvent the problem of having to explicitly manage the memory,
|
||||
while still keeping the benefits of the dedicated physical memories, by
|
||||
supporting the concept of unified memory. This enables the CPU and the GPUs in
|
||||
the system to access host and other GPUs' memory without explicit memory
|
||||
management.
|
||||
|
||||
Unified memory
|
||||
================================================================================
|
||||
|
||||
Unified Memory is a single memory address space accessible from any processor
|
||||
within a system. This setup simplifies memory management and enables
|
||||
applications to allocate data that can be read or written on both CPUs and GPUs
|
||||
without explicitly copying it to the specific CPU or GPU. The Unified memory
|
||||
model is shown in the following figure.
|
||||
|
||||
.. figure:: ../../../data/how-to/hip_runtime_api/memory_management/unified_memory/um.svg
|
||||
|
||||
Unified memory enables the access to memory located on other devices via
|
||||
several methods, depending on whether hardware support is available or has to be
|
||||
managed by the driver.
|
||||
|
||||
Hardware supported on-demand page migration
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
When a kernel on the device tries to access a memory address that is not in its
|
||||
memory, a page-fault is triggered. The GPU then in turn requests the page from
|
||||
the host or an other device, on which the memory is located. The page is then
|
||||
unmapped from the source, sent to the device and mapped to the device's memory.
|
||||
The requested memory is then available to the processes running on the device.
|
||||
|
||||
In case the device's memory is at capacity, a page is unmapped from the device's
|
||||
memory first and sent and mapped to host memory. This enables more memory to be
|
||||
allocated and used for a GPU, than the GPU itself has physically available.
|
||||
|
||||
This level of unified memory support can be very beneficial for sparse accesses
|
||||
to an array, that is not often used on the device.
|
||||
|
||||
Driver managed page migration
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
If the hardware does not support on-demand page migration, then all the pages
|
||||
accessed by a kernel have to be resident on the device, so they have to be
|
||||
migrated before the kernel is running. Since the driver can not know beforehand,
|
||||
what parts of an array are going to be accessed, all pages of all accessed
|
||||
arrays have to be migrated. This can lead to significant delays on the first run
|
||||
of a kernel, on top of possibly copying more memory than is actually accessed by
|
||||
the kernel.
|
||||
|
||||
.. _unified memory system requirements:
|
||||
|
||||
System requirements
|
||||
================================================================================
|
||||
|
||||
Unified memory is supported on Linux by all modern AMD GPUs from the Vega
|
||||
series onward, as shown in the following table. Unified memory management can
|
||||
be achieved by explicitly allocating managed memory using
|
||||
:cpp:func:`hipMallocManaged` or marking variables with the ``__managed__``
|
||||
attribute. For the latest GPUs, with a Linux kernel that supports
|
||||
`Heterogeneous Memory Management (HMM)
|
||||
<https://www.kernel.org/doc/html/latest/mm/hmm.html>`_, the normal system
|
||||
allocator can be used.
|
||||
|
||||
.. list-table:: Supported Unified Memory Allocators by GPU architecture
|
||||
:widths: 40, 25, 25
|
||||
:header-rows: 1
|
||||
:align: center
|
||||
|
||||
* - Architecture
|
||||
- :cpp:func:`hipMallocManaged()`, ``__managed__``
|
||||
- ``new``, ``malloc()``
|
||||
* - CDNA3
|
||||
- ✅
|
||||
- ✅ :sup:`1`
|
||||
* - CDNA2
|
||||
- ✅
|
||||
- ✅ :sup:`1`
|
||||
* - CDNA1
|
||||
- ✅
|
||||
- ✅ :sup:`1`
|
||||
* - RDNA1
|
||||
- ✅
|
||||
- ❌
|
||||
* - GCN5
|
||||
- ✅
|
||||
- ❌
|
||||
|
||||
✅: **Supported**
|
||||
|
||||
❌: **Unsupported**
|
||||
|
||||
:sup:`1` Works only with ``HSA_XNACK=1`` and kernels with HMM support. First GPU
|
||||
access causes recoverable page-fault.
|
||||
|
||||
.. _unified memory allocators:
|
||||
|
||||
Unified memory allocators
|
||||
================================================================================
|
||||
|
||||
Support for the different unified memory allocators depends on the GPU
|
||||
architecture and on the system. For more information, see :ref:`unified memory
|
||||
system requirements` and :ref:`checking unified memory support`.
|
||||
|
||||
- **HIP allocated managed memory and variables**
|
||||
|
||||
:cpp:func:`hipMallocManaged()` is a dynamic memory allocator available on
|
||||
all GPUs with unified memory support. For more details, visit
|
||||
:ref:`unified_memory_reference`.
|
||||
|
||||
The ``__managed__`` declaration specifier, which serves as its counterpart,
|
||||
can be utilized for static allocation.
|
||||
|
||||
- **System allocated unified memory**
|
||||
|
||||
Starting with CDNA2, the ``new`` and ``malloc()`` system allocators allow
|
||||
you to reserve unified memory. The system allocator is more versatile and
|
||||
offers an easy transition for code written for CPUs to HIP code as the
|
||||
same system allocation API is used.
|
||||
|
||||
To ensure the proper functioning of system allocated unified memory on supported
|
||||
GPUs, it is essential to set the environment variable ``HSA_XNACK=1`` and use
|
||||
a GPU kernel mode driver that supports HMM
|
||||
<https://www.kernel.org/doc/html/latest/mm/hmm.html>`_. Without this
|
||||
configuration, the behavior will be similar to that of systems without HMM
|
||||
support.
|
||||
|
||||
The table below illustrates the expected behavior of managed and unified memory
|
||||
functions on ROCm and CUDA, both with and without HMM support.
|
||||
|
||||
.. tab-set::
|
||||
.. tab-item:: ROCm allocation behaviour
|
||||
:sync: original-block
|
||||
|
||||
.. list-table:: Comparison of expected behavior of managed and unified memory functions in ROCm
|
||||
:widths: 26, 17, 20, 17, 20
|
||||
:header-rows: 1
|
||||
|
||||
* - call
|
||||
- Allocation origin without HMM or ``HSA_XNACK=0``
|
||||
- Access outside the origin without HMM or ``HSA_XNACK=0``
|
||||
- Allocation origin with HMM and ``HSA_XNACK=1``
|
||||
- Access outside the origin with HMM and ``HSA_XNACK=1``
|
||||
* - ``new``, ``malloc()``
|
||||
- host
|
||||
- not accessible on device
|
||||
- host
|
||||
- page-fault migration
|
||||
* - :cpp:func:`hipMalloc()`
|
||||
- device
|
||||
- zero copy [zc]_
|
||||
- device
|
||||
- zero copy [zc]_
|
||||
* - :cpp:func:`hipMallocManaged()`, ``__managed__``
|
||||
- pinned host
|
||||
- zero copy [zc]_
|
||||
- host
|
||||
- page-fault migration
|
||||
* - :cpp:func:`hipHostRegister()`
|
||||
- undefined behavior
|
||||
- undefined behavior
|
||||
- host
|
||||
- page-fault migration
|
||||
* - :cpp:func:`hipHostMalloc()`
|
||||
- pinned host
|
||||
- zero copy [zc]_
|
||||
- pinned host
|
||||
- zero copy [zc]_
|
||||
|
||||
.. tab-item:: CUDA allocation behaviour
|
||||
:sync: cooperative-groups
|
||||
|
||||
.. list-table:: Comparison of expected behavior of managed and unified memory functions in CUDA
|
||||
:widths: 26, 17, 20, 17, 20
|
||||
:header-rows: 1
|
||||
|
||||
* - call
|
||||
- Allocation origin without HMM
|
||||
- Access outside the origin without HMM
|
||||
- Allocation origin with HMM
|
||||
- Access outside the origin with HMM
|
||||
* - ``new``, ``malloc()``
|
||||
- host
|
||||
- not accessible on device
|
||||
- first touch
|
||||
- page-fault migration
|
||||
* - ``cudaMalloc()``
|
||||
- device
|
||||
- not accessible on host
|
||||
- device
|
||||
- page-fault migration
|
||||
* - ``cudaMallocManaged()``, ``__managed__``
|
||||
- host
|
||||
- page-fault migration
|
||||
- first touch
|
||||
- page-fault migration
|
||||
* - ``cudaHostRegister()``
|
||||
- host
|
||||
- page-fault migration
|
||||
- host
|
||||
- page-fault migration
|
||||
* - ``cudaMallocHost()``
|
||||
- pinned host
|
||||
- zero copy [zc]_
|
||||
- pinned host
|
||||
- zero copy [zc]_
|
||||
|
||||
.. [zc] Zero copy is a feature, where the memory is pinned to either the device
|
||||
or the host, and won't be transferred when accessed by another device or
|
||||
the host. Instead only the requested memory is transferred, without
|
||||
making an explicit copy, like a normal memory access, hence the term
|
||||
"zero copy".
|
||||
|
||||
.. _checking unified memory support:
|
||||
|
||||
Checking unified memory support
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
The following device attributes can offer information about which :ref:`unified
|
||||
memory allocators` are supported. The attribute value is 1 if the functionality
|
||||
is supported, and 0 if it is not supported.
|
||||
|
||||
.. list-table:: Device attributes for unified memory management
|
||||
:widths: 40, 60
|
||||
:header-rows: 1
|
||||
:align: center
|
||||
|
||||
* - Attribute
|
||||
- Description
|
||||
* - :cpp:enumerator:`hipDeviceAttributeManagedMemory`
|
||||
- Device supports allocating managed memory on this system
|
||||
* - :cpp:enumerator:`hipDeviceAttributePageableMemoryAccess`
|
||||
- Device supports coherently accessing pageable memory without calling :cpp:func:`hipHostRegister()` on it.
|
||||
* - :cpp:enumerator:`hipDeviceAttributeConcurrentManagedAccess`
|
||||
- Full unified memory support. Device can coherently access managed memory concurrently with the CPU
|
||||
|
||||
For details on how to get the attributes of a specific device see :cpp:func:`hipDeviceGetAttribute()`.
|
||||
|
||||
Example for unified memory management
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
The following example shows how to use unified memory with
|
||||
:cpp:func:`hipMallocManaged()` for dynamic allocation, the ``__managed__`` attribute
|
||||
for static allocation and the standard ``new`` allocation. For comparison, the
|
||||
explicit memory management example is presented in the last tab.
|
||||
|
||||
.. tab-set::
|
||||
|
||||
.. tab-item:: hipMallocManaged()
|
||||
|
||||
.. code-block:: cpp
|
||||
:emphasize-lines: 22-25
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <iostream>
|
||||
|
||||
#define HIP_CHECK(expression) \
|
||||
{ \
|
||||
const hipError_t err = expression; \
|
||||
if(err != hipSuccess){ \
|
||||
std::cerr << "HIP error: " \
|
||||
<< hipGetErrorString(err) \
|
||||
<< " at " << __LINE__ << "\n"; \
|
||||
} \
|
||||
}
|
||||
|
||||
// Addition of two values.
|
||||
__global__ void add(int *a, int *b, int *c) {
|
||||
*c = *a + *b;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int *a, *b, *c;
|
||||
|
||||
// Allocate memory for a, b and c that is accessible to both device and host codes.
|
||||
HIP_CHECK(hipMallocManaged(&a, sizeof(*a)));
|
||||
HIP_CHECK(hipMallocManaged(&b, sizeof(*b)));
|
||||
HIP_CHECK(hipMallocManaged(&c, sizeof(*c)));
|
||||
|
||||
// Setup input values.
|
||||
*a = 1;
|
||||
*b = 2;
|
||||
|
||||
// Launch add() kernel on GPU.
|
||||
hipLaunchKernelGGL(add, dim3(1), dim3(1), 0, 0, a, b, c);
|
||||
|
||||
// Wait for GPU to finish before accessing on host.
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
|
||||
// Print the result.
|
||||
std::cout << *a << " + " << *b << " = " << *c << std::endl;
|
||||
|
||||
// Cleanup allocated memory.
|
||||
HIP_CHECK(hipFree(a));
|
||||
HIP_CHECK(hipFree(b));
|
||||
HIP_CHECK(hipFree(c));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
.. tab-item:: __managed__
|
||||
|
||||
.. code-block:: cpp
|
||||
:emphasize-lines: 19-20
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <iostream>
|
||||
|
||||
#define HIP_CHECK(expression) \
|
||||
{ \
|
||||
const hipError_t err = expression; \
|
||||
if(err != hipSuccess){ \
|
||||
std::cerr << "HIP error: " \
|
||||
<< hipGetErrorString(err) \
|
||||
<< " at " << __LINE__ << "\n"; \
|
||||
} \
|
||||
}
|
||||
|
||||
// Addition of two values.
|
||||
__global__ void add(int *a, int *b, int *c) {
|
||||
*c = *a + *b;
|
||||
}
|
||||
|
||||
// Declare a, b and c as static variables.
|
||||
__managed__ int a, b, c;
|
||||
|
||||
int main() {
|
||||
// Setup input values.
|
||||
a = 1;
|
||||
b = 2;
|
||||
|
||||
// Launch add() kernel on GPU.
|
||||
hipLaunchKernelGGL(add, dim3(1), dim3(1), 0, 0, &a, &b, &c);
|
||||
|
||||
// Wait for GPU to finish before accessing on host.
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
|
||||
// Prints the result.
|
||||
std::cout << a << " + " << b << " = " << c << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
.. tab-item:: new
|
||||
|
||||
.. code-block:: cpp
|
||||
:emphasize-lines: 20-23
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <iostream>
|
||||
|
||||
#define HIP_CHECK(expression) \
|
||||
{ \
|
||||
const hipError_t err = expression; \
|
||||
if(err != hipSuccess){ \
|
||||
std::cerr << "HIP error: " \
|
||||
<< hipGetErrorString(err) \
|
||||
<< " at " << __LINE__ << "\n"; \
|
||||
} \
|
||||
}
|
||||
|
||||
// Addition of two values.
|
||||
__global__ void add(int* a, int* b, int* c) {
|
||||
*c = *a + *b;
|
||||
}
|
||||
|
||||
// This example requires HMM support and the environment variable HSA_XNACK needs to be set to 1
|
||||
int main() {
|
||||
// Allocate memory for a, b, and c.
|
||||
int *a = new int[1];
|
||||
int *b = new int[1];
|
||||
int *c = new int[1];
|
||||
|
||||
// Setup input values.
|
||||
*a = 1;
|
||||
*b = 2;
|
||||
|
||||
// Launch add() kernel on GPU.
|
||||
hipLaunchKernelGGL(add, dim3(1), dim3(1), 0, 0, a, b, c);
|
||||
|
||||
// Wait for GPU to finish before accessing on host.
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
|
||||
// Prints the result.
|
||||
std::cout << *a << " + " << *b << " = " << *c << std::endl;
|
||||
|
||||
// Cleanup allocated memory.
|
||||
delete[] a;
|
||||
delete[] b;
|
||||
delete[] c;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
.. tab-item:: Explicit Memory Management
|
||||
|
||||
.. code-block:: cpp
|
||||
:emphasize-lines: 27-34, 39-40
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <iostream>
|
||||
|
||||
#define HIP_CHECK(expression) \
|
||||
{ \
|
||||
const hipError_t err = expression; \
|
||||
if(err != hipSuccess){ \
|
||||
std::cerr << "HIP error: " \
|
||||
<< hipGetErrorString(err) \
|
||||
<< " at " << __LINE__ << "\n"; \
|
||||
} \
|
||||
}
|
||||
|
||||
// Addition of two values.
|
||||
__global__ void add(int *a, int *b, int *c) {
|
||||
*c = *a + *b;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int a, b, c;
|
||||
int *d_a, *d_b, *d_c;
|
||||
|
||||
// Setup input values.
|
||||
a = 1;
|
||||
b = 2;
|
||||
|
||||
// Allocate device copies of a, b and c.
|
||||
HIP_CHECK(hipMalloc(&d_a, sizeof(*d_a)));
|
||||
HIP_CHECK(hipMalloc(&d_b, sizeof(*d_b)));
|
||||
HIP_CHECK(hipMalloc(&d_c, sizeof(*d_c)));
|
||||
|
||||
// Copy input values to device.
|
||||
HIP_CHECK(hipMemcpy(d_a, &a, sizeof(*d_a), hipMemcpyHostToDevice));
|
||||
HIP_CHECK(hipMemcpy(d_b, &b, sizeof(*d_b), hipMemcpyHostToDevice));
|
||||
|
||||
// Launch add() kernel on GPU.
|
||||
hipLaunchKernelGGL(add, dim3(1), dim3(1), 0, 0, d_a, d_b, d_c);
|
||||
|
||||
// Copy the result back to the host.
|
||||
HIP_CHECK(hipMemcpy(&c, d_c, sizeof(*d_c), hipMemcpyDeviceToHost));
|
||||
|
||||
// Cleanup allocated memory.
|
||||
HIP_CHECK(hipFree(d_a));
|
||||
HIP_CHECK(hipFree(d_b));
|
||||
HIP_CHECK(hipFree(d_c));
|
||||
|
||||
// Prints the result.
|
||||
std::cout << a << " + " << b << " = " << c << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
.. _using unified memory:
|
||||
|
||||
Using unified memory
|
||||
================================================================================
|
||||
|
||||
Unified memory can simplify the complexities of memory management in GPU
|
||||
computing, by not requiring explicit copies between the host and the devices. It
|
||||
can be particularly useful in use cases with sparse memory accesses from both
|
||||
the CPU and the GPU, as only the parts of the memory region that are actually
|
||||
accessed need to be transferred to the corresponding processor, not the whole
|
||||
memory region. This reduces the amount of memory sent over the PCIe bus or other
|
||||
interfaces.
|
||||
|
||||
In HIP, pinned memory allocations are coherent by default. Pinned memory is
|
||||
host memory mapped into the address space of all GPUs, meaning that the pointer
|
||||
can be used on both host and device. Additionally, using pinned memory instead of
|
||||
pageable memory on the host can improve bandwidth for transfers between the host
|
||||
and the GPUs.
|
||||
|
||||
While unified memory can provide numerous benefits, it's important to be aware
|
||||
of the potential performance overhead associated with unified memory. You must
|
||||
thoroughly test and profile your code to ensure it's the most suitable choice
|
||||
for your use case.
|
||||
|
||||
.. _unified memory runtime hints:
|
||||
|
||||
Performance optimizations for unified memory
|
||||
================================================================================
|
||||
|
||||
There are several ways, in which the developer can guide the runtime to reduce
|
||||
copies between devices, in order to improve performance.
|
||||
|
||||
Data prefetching
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Data prefetching is a technique used to improve the performance of your
|
||||
application by moving data to the desired device before it's actually
|
||||
needed. ``hipCpuDeviceId`` is a special constant to specify the CPU as target.
|
||||
|
||||
.. code-block:: cpp
|
||||
:emphasize-lines: 33-36,41-42
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <iostream>
|
||||
|
||||
#define HIP_CHECK(expression) \
|
||||
{ \
|
||||
const hipError_t err = expression; \
|
||||
if(err != hipSuccess){ \
|
||||
std::cerr << "HIP error: " \
|
||||
<< hipGetErrorString(err) \
|
||||
<< " at " << __LINE__ << "\n"; \
|
||||
} \
|
||||
}
|
||||
|
||||
// Addition of two values.
|
||||
__global__ void add(int *a, int *b, int *c) {
|
||||
*c = *a + *b;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int *a, *b, *c;
|
||||
int deviceId;
|
||||
HIP_CHECK(hipGetDevice(&deviceId)); // Get the current device ID
|
||||
|
||||
// Allocate memory for a, b and c that is accessible to both device and host codes.
|
||||
HIP_CHECK(hipMallocManaged(&a, sizeof(*a)));
|
||||
HIP_CHECK(hipMallocManaged(&b, sizeof(*b)));
|
||||
HIP_CHECK(hipMallocManaged(&c, sizeof(*c)));
|
||||
|
||||
// Setup input values.
|
||||
*a = 1;
|
||||
*b = 2;
|
||||
|
||||
// Prefetch the data to the GPU device.
|
||||
HIP_CHECK(hipMemPrefetchAsync(a, sizeof(*a), deviceId, 0));
|
||||
HIP_CHECK(hipMemPrefetchAsync(b, sizeof(*b), deviceId, 0));
|
||||
HIP_CHECK(hipMemPrefetchAsync(c, sizeof(*c), deviceId, 0));
|
||||
|
||||
// Launch add() kernel on GPU.
|
||||
hipLaunchKernelGGL(add, dim3(1), dim3(1), 0, 0, a, b, c);
|
||||
|
||||
// Prefetch the result back to the CPU.
|
||||
HIP_CHECK(hipMemPrefetchAsync(c, sizeof(*c), hipCpuDeviceId, 0));
|
||||
|
||||
// Wait for the prefetch operations to complete.
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
|
||||
// Prints the result.
|
||||
std::cout << *a << " + " << *b << " = " << *c << std::endl;
|
||||
|
||||
// Cleanup allocated memory.
|
||||
HIP_CHECK(hipFree(a));
|
||||
HIP_CHECK(hipFree(b));
|
||||
HIP_CHECK(hipFree(c));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Memory advice
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Unified memory runtime hints can be set with :cpp:func:`hipMemAdvise()` to help
|
||||
improve the performance of your code if you know the memory usage pattern. There
|
||||
are several different types of hints as specified in the enum
|
||||
:cpp:enum:`hipMemoryAdvise`, for example, whether a certain device mostly reads
|
||||
the memory region, where it should ideally be located, and even whether that
|
||||
specific memory region is accessed by a specific device.
|
||||
|
||||
For the best performance, profile your application to optimize the
|
||||
utilization of HIP runtime hints.
|
||||
|
||||
The effectiveness of :cpp:func:`hipMemAdvise()` comes from its ability to inform
|
||||
the runtime of the developer's intentions regarding memory usage. When the
|
||||
runtime has knowledge of the expected memory access patterns, it can make better
|
||||
decisions about data placement, leading to less transfers via the interconnect
|
||||
and thereby reduced latency and bandwidth requirements. However, the actual
|
||||
impact on performance can vary based on the specific use case and the system.
|
||||
|
||||
The following is the updated version of the example above with memory advice
|
||||
instead of prefetching.
|
||||
|
||||
.. code-block:: cpp
|
||||
:emphasize-lines: 29-41
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <iostream>
|
||||
|
||||
#define HIP_CHECK(expression) \
|
||||
{ \
|
||||
const hipError_t err = expression; \
|
||||
if(err != hipSuccess){ \
|
||||
std::cerr << "HIP error: " \
|
||||
<< hipGetErrorString(err) \
|
||||
<< " at " << __LINE__ << "\n"; \
|
||||
} \
|
||||
}
|
||||
|
||||
// Addition of two values.
|
||||
__global__ void add(int *a, int *b, int *c) {
|
||||
*c = *a + *b;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int deviceId;
|
||||
HIP_CHECK(hipGetDevice(&deviceId));
|
||||
int *a, *b, *c;
|
||||
|
||||
// Allocate memory for a, b, and c accessible to both device and host codes.
|
||||
HIP_CHECK(hipMallocManaged(&a, sizeof(*a)));
|
||||
HIP_CHECK(hipMallocManaged(&b, sizeof(*b)));
|
||||
HIP_CHECK(hipMallocManaged(&c, sizeof(*c)));
|
||||
|
||||
// Set memory advice for a and b to be read, located on and accessed by the GPU.
|
||||
HIP_CHECK(hipMemAdvise(a, sizeof(*a), hipMemAdviseSetPreferredLocation, deviceId));
|
||||
HIP_CHECK(hipMemAdvise(a, sizeof(*a), hipMemAdviseSetAccessedBy, deviceId));
|
||||
HIP_CHECK(hipMemAdvise(a, sizeof(*a), hipMemAdviseSetReadMostly, deviceId));
|
||||
|
||||
HIP_CHECK(hipMemAdvise(b, sizeof(*b), hipMemAdviseSetPreferredLocation, deviceId));
|
||||
HIP_CHECK(hipMemAdvise(b, sizeof(*b), hipMemAdviseSetAccessedBy, deviceId));
|
||||
HIP_CHECK(hipMemAdvise(b, sizeof(*b), hipMemAdviseSetReadMostly, deviceId));
|
||||
|
||||
// Set memory advice for c to be read, located on and accessed by the CPU.
|
||||
HIP_CHECK(hipMemAdvise(c, sizeof(*c), hipMemAdviseSetPreferredLocation, hipCpuDeviceId));
|
||||
HIP_CHECK(hipMemAdvise(c, sizeof(*c), hipMemAdviseSetAccessedBy, hipCpuDeviceId));
|
||||
HIP_CHECK(hipMemAdvise(c, sizeof(*c), hipMemAdviseSetReadMostly, hipCpuDeviceId));
|
||||
|
||||
// Setup input values.
|
||||
*a = 1;
|
||||
*b = 2;
|
||||
|
||||
// Launch add() kernel on GPU.
|
||||
hipLaunchKernelGGL(add, dim3(1), dim3(1), 0, 0, a, b, c);
|
||||
|
||||
// Wait for GPU to finish before accessing on host.
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
|
||||
// Prints the result.
|
||||
std::cout << *a << " + " << *b << " = " << *c << std::endl;
|
||||
|
||||
// Cleanup allocated memory.
|
||||
HIP_CHECK(hipFree(a));
|
||||
HIP_CHECK(hipFree(b));
|
||||
HIP_CHECK(hipFree(c));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Memory range attributes
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
:cpp:func:`hipMemRangeGetAttribute()` allows you to query attributes of a given
|
||||
memory range. The attributes are given in :cpp:enum:`hipMemRangeAttribute`.
|
||||
|
||||
.. code-block:: cpp
|
||||
:emphasize-lines: 44-49
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <iostream>
|
||||
|
||||
#define HIP_CHECK(expression) \
|
||||
{ \
|
||||
const hipError_t err = expression; \
|
||||
if(err != hipSuccess){ \
|
||||
std::cerr << "HIP error: " \
|
||||
<< hipGetErrorString(err) \
|
||||
<< " at " << __LINE__ << "\n"; \
|
||||
} \
|
||||
}
|
||||
|
||||
// Addition of two values.
|
||||
__global__ void add(int *a, int *b, int *c) {
|
||||
*c = *a + *b;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int *a, *b, *c;
|
||||
unsigned int attributeValue;
|
||||
constexpr size_t attributeSize = sizeof(attributeValue);
|
||||
|
||||
int deviceId;
|
||||
HIP_CHECK(hipGetDevice(&deviceId));
|
||||
|
||||
// Allocate memory for a, b and c that is accessible to both device and host codes.
|
||||
HIP_CHECK(hipMallocManaged(&a, sizeof(*a)));
|
||||
HIP_CHECK(hipMallocManaged(&b, sizeof(*b)));
|
||||
HIP_CHECK(hipMallocManaged(&c, sizeof(*c)));
|
||||
|
||||
// Setup input values.
|
||||
*a = 1;
|
||||
*b = 2;
|
||||
|
||||
HIP_CHECK(hipMemAdvise(a, sizeof(*a), hipMemAdviseSetReadMostly, deviceId));
|
||||
|
||||
// Launch add() kernel on GPU.
|
||||
hipLaunchKernelGGL(add, dim3(1), dim3(1), 0, 0, a, b, c);
|
||||
|
||||
// Wait for GPU to finish before accessing on host.
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
|
||||
// Query an attribute of the memory range.
|
||||
HIP_CHECK(hipMemRangeGetAttribute(&attributeValue,
|
||||
attributeSize,
|
||||
hipMemRangeAttributeReadMostly,
|
||||
a,
|
||||
sizeof(*a)));
|
||||
|
||||
// Prints the result.
|
||||
std::cout << *a << " + " << *b << " = " << *c << std::endl;
|
||||
std::cout << "The array a is" << (attributeValue == 1 ? "" : " NOT") << " set to hipMemRangeAttributeReadMostly" << std::endl;
|
||||
|
||||
// Cleanup allocated memory.
|
||||
HIP_CHECK(hipFree(a));
|
||||
HIP_CHECK(hipFree(b));
|
||||
HIP_CHECK(hipFree(c));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Asynchronously attach memory to a stream
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
The :cpp:func:`hipStreamAttachMemAsync()` function attaches memory to a stream,
|
||||
which can reduce the amount of memory transferred, when managed memory is used.
|
||||
When the memory is attached to a stream using this function, it only gets
|
||||
transferred between devices, when a kernel that is launched on this stream needs
|
||||
access to the memory.
|
||||
@@ -0,0 +1,387 @@
|
||||
.. meta::
|
||||
:description: This chapter describes introduces Virtual Memory (VM) and shows
|
||||
how to use it in AMD HIP.
|
||||
:keywords: AMD, ROCm, HIP, CUDA, virtual memory, virtual, memory, UM, APU
|
||||
|
||||
.. _virtual_memory:
|
||||
|
||||
********************************************************************************
|
||||
Virtual memory management
|
||||
********************************************************************************
|
||||
|
||||
Memory management is important when creating high-performance applications in
|
||||
the HIP ecosystem. Both allocating and copying memory can result in bottlenecks,
|
||||
which can significantly impact performance.
|
||||
|
||||
Global memory allocation in HIP uses the C language style allocation function.
|
||||
This works fine for simple cases but can cause problems if your memory needs
|
||||
change. If you need to increase the size of your memory, you must allocate a
|
||||
second larger buffer and copy the data to it before you can free the original
|
||||
buffer. This increases overall memory usage and causes unnecessary ``memcpy``
|
||||
calls. Another solution is to allocate a larger buffer than you initially need.
|
||||
However, this isn't an efficient way to handle resources and doesn't solve the
|
||||
issue of reallocation when the extra buffer runs out.
|
||||
|
||||
Virtual memory management solves these memory management problems. It helps to
|
||||
reduce memory usage and unnecessary ``memcpy`` calls.
|
||||
|
||||
HIP virtual memory management is built on top of HSA, which provides low-level
|
||||
access to AMD GPU memory. For more details on the underlying HSA runtime,
|
||||
see :doc:`ROCr documentation <rocr-runtime:index>`
|
||||
|
||||
.. _memory_allocation_virtual_memory:
|
||||
|
||||
Memory allocation
|
||||
=================
|
||||
|
||||
Standard memory allocation uses the :cpp:func:`hipMalloc` function to allocate a
|
||||
block of memory on the device. However, when using virtual memory, this process
|
||||
is separated into multiple steps using the :cpp:func:`hipMemCreate`,
|
||||
:cpp:func:`hipMemAddressReserve`, :cpp:func:`hipMemMap`, and
|
||||
:cpp:func:`hipMemSetAccess` functions. This guide explains what these functions
|
||||
do and how you can use them for virtual memory management.
|
||||
|
||||
.. _vmm_support:
|
||||
|
||||
Virtual memory management support
|
||||
---------------------------------
|
||||
|
||||
The first step is to check if the targeted device or GPU supports virtual memory management.
|
||||
Use the :cpp:func:`hipDeviceGetAttribute` function to get the
|
||||
``hipDeviceAttributeVirtualMemoryManagementSupported`` attribute for a specific GPU, as shown in the following example.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
int vmm = 0, currentDev = 0;
|
||||
hipDeviceGetAttribute(
|
||||
&vmm, hipDeviceAttributeVirtualMemoryManagementSupported, currentDev
|
||||
);
|
||||
|
||||
if (vmm == 0) {
|
||||
std::cout << "GPU " << currentDev << " doesn't support virtual memory management." << std::endl;
|
||||
} else {
|
||||
std::cout << "GPU " << currentDev << " support virtual memory management." << std::endl;
|
||||
}
|
||||
|
||||
.. _allocate_physical_memory:
|
||||
|
||||
Allocate physical memory
|
||||
------------------------
|
||||
|
||||
The next step is to allocate the physical memory using the
|
||||
:cpp:func:`hipMemCreate` function. This function accepts the size of the buffer,
|
||||
an ``unsigned long long`` variable for the flags, and a
|
||||
:cpp:struct:`hipMemAllocationProp` variable. :cpp:struct:`hipMemAllocationProp`
|
||||
contains the properties of the memory to be allocated, such as where the memory
|
||||
is physically located and what kind of shareable handles are available. If the
|
||||
allocation is successful, the function returns a value of
|
||||
:cpp:enumerator:`hipSuccess`, with :cpp:type:`hipMemGenericAllocationHandle_t`
|
||||
representing a valid physical memory allocation.
|
||||
|
||||
The allocated memory must be aligned with the appropriate granularity. The
|
||||
granularity value can be queried with :cpp:func:`hipMemGetAllocationGranularity`,
|
||||
and its value depends on the target device hardware and the type of memory
|
||||
allocation. If the allocation size is not aligned, meaning it is not cleanly
|
||||
divisible by the minimum granularity value, :cpp:func:`hipMemCreate` will return
|
||||
an out-of-memory error.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
size_t granularity = 0;
|
||||
hipMemGenericAllocationHandle_t allocHandle;
|
||||
hipMemAllocationProp prop = {};
|
||||
// The pinned allocation type cannot be migrated from its current location
|
||||
// while the application is actively using it.
|
||||
prop.type = hipMemAllocationTypePinned;
|
||||
// Set the location type to device, currently there are no other valid option.
|
||||
prop.location.type = hipMemLocationTypeDevice;
|
||||
// Set the device id, where the memory will be allocated.
|
||||
prop.location.id = currentDev;
|
||||
hipMemGetAllocationGranularity(&granularity, &prop, hipMemAllocationGranularityMinimum);
|
||||
padded_size = ROUND_UP(size, granularity);
|
||||
hipMemCreate(&allocHandle, padded_size, &prop, 0);
|
||||
|
||||
.. _reserve_virtual_address:
|
||||
|
||||
Reserve virtual address range
|
||||
-----------------------------
|
||||
|
||||
After you have acquired an allocation of physical memory, you must map it to a
|
||||
virtual address before you can use it. Mapping means the physical memory
|
||||
allocation is available from the virtual address range it is mapped to. To
|
||||
reserve a virtual memory range, use the :cpp:func:`hipMemAddressReserve`
|
||||
function. The size of the virtual memory must match the amount of physical
|
||||
memory previously allocated. You can then map the physical memory allocation to
|
||||
the newly-acquired virtual memory address range using the :cpp:func:`hipMemMap`
|
||||
function.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
hipMemAddressReserve(&ptr, padded_size, 0, 0, 0);
|
||||
hipMemMap(ptr, padded_size, 0, allocHandle, 0);
|
||||
|
||||
.. _set_memory_access:
|
||||
|
||||
Set memory access
|
||||
-----------------
|
||||
|
||||
Finally, use the :cpp:func:`hipMemSetAccess` function to enable memory access.
|
||||
It accepts the pointer to the virtual memory, the size, and a
|
||||
:cpp:struct:`hipMemAccessDesc` descriptor as parameters. In a multi-GPU
|
||||
environment, you can map the device memory of one GPU to another. This feature
|
||||
also works with the traditional memory management system, but isn't as scalable
|
||||
as with virtual memory. When memory is allocated with :cpp:func:`hipMalloc`,
|
||||
:cpp:func:`hipDeviceEnablePeerAccess` is used to enable peer access. This
|
||||
function enables access between two devices, but it means that every call to
|
||||
:cpp:func:`hipMalloc` takes more time to perform the checks and the mapping
|
||||
between the devices. When using virtual memory management, peer access is
|
||||
enabled by :cpp:func:`hipMemSetAccess`, which provides a finer level of
|
||||
control over what is shared. This has no performance impact on memory allocation
|
||||
and gives you more control over what memory buffers are shared with which
|
||||
devices.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
hipMemAccessDesc accessDesc = {};
|
||||
accessDesc.location.type = hipMemLocationTypeDevice;
|
||||
accessDesc.location.id = currentDev;
|
||||
accessDesc.flags = hipMemAccessFlagsProtReadwrite;
|
||||
hipMemSetAccess(ptr, padded_size, &accessDesc, 1);
|
||||
|
||||
At this point the memory is allocated, mapped, and ready for use. You can read
|
||||
and write to it, just like you would a C style memory allocation.
|
||||
|
||||
.. _usage_virtual_memory:
|
||||
|
||||
Dynamically increase allocation size
|
||||
------------------------------------
|
||||
|
||||
To increase the amount of pre-allocated memory, use
|
||||
:cpp:func:`hipMemAddressReserve`, which accepts the starting address, and the
|
||||
size of the reservation in bytes. This allows you to have a continuous virtual
|
||||
address space without worrying about the underlying physical allocation.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
hipMemAddressReserve(&new_ptr, (new_size - padded_size), 0, ptr + padded_size, 0);
|
||||
hipMemMap(new_ptr, (new_size - padded_size), 0, newAllocHandle, 0);
|
||||
hipMemSetAccess(new_ptr, (new_size - padded_size), &accessDesc, 1);
|
||||
|
||||
The code sample above assumes that :cpp:func:`hipMemAddressReserve` was able to
|
||||
reserve the memory address at the specified location. However, this isn't
|
||||
guaranteed to be true, so you should validate that ``new_ptr`` points to a
|
||||
specific virtual address before using it.
|
||||
|
||||
.. _free_virtual_memory:
|
||||
|
||||
Free virtual memory
|
||||
-------------------
|
||||
|
||||
To free the memory allocated in this manner, use the corresponding free
|
||||
functions. To unmap the memory, use :cpp:func:`hipMemUnmap`. To release the
|
||||
virtual address range, use :cpp:func:`hipMemAddressFree`. Finally, to release
|
||||
the physical memory, use :cpp:func:`hipMemRelease`. A side effect of these
|
||||
functions is the lack of synchronization when memory is released. If you call
|
||||
:cpp:func:`hipFree` when you have multiple streams running in parallel, it
|
||||
synchronizes the device. This causes worse resource usage and performance.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
hipMemUnmap(ptr, size);
|
||||
hipMemRelease(allocHandle);
|
||||
hipMemAddressFree(ptr, size);
|
||||
|
||||
Example code
|
||||
============
|
||||
|
||||
The virtual memory management example follows these steps:
|
||||
|
||||
1. Check virtual memory management :ref:`support <vmm_support>`:
|
||||
The :cpp:func:`hipDeviceGetAttribute` function is used to check the virtual
|
||||
memory management support of the GPU with ID 0.
|
||||
|
||||
2. Physical memory :ref:`allocation <allocate_physical_memory>`: Physical memory
|
||||
is allocated using :cpp:func:`hipMemCreate` with pinned memory on the
|
||||
device.
|
||||
|
||||
3. Virtual memory :ref:`reservation <reserve_virtual_address>`: Virtual address
|
||||
range is reserved using :cpp:func:`hipMemAddressReserve`.
|
||||
|
||||
4. Mapping virtual address to physical memory: The physical memory is mapped
|
||||
to a virtual address (``virtualPointer``) using :cpp:func:`hipMemMap`.
|
||||
|
||||
5. Memory :ref:`access permissions<set_memory_access>`: Permission is set for
|
||||
pointer to allow read and write access using :cpp:func:`hipMemSetAccess`.
|
||||
|
||||
6. Memory operation: Data is written to the memory via ``virtualPointer``.
|
||||
|
||||
7. Launch kernels: The ``zeroAddr`` and ``fillAddr`` kernels are
|
||||
launched using the virtual memory pointer.
|
||||
|
||||
8. :ref:`Cleanup <free_virtual_memory>`: The mappings, physical memory, and
|
||||
virtual address are released at the end to avoid memory leaks.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <iostream>
|
||||
|
||||
#define ROUND_UP(SIZE,GRANULARITY) ((1 + SIZE / GRANULARITY) * GRANULARITY)
|
||||
|
||||
#define HIP_CHECK(expression) \
|
||||
{ \
|
||||
const hipError_t err = expression; \
|
||||
if(err != hipSuccess){ \
|
||||
std::cerr << "HIP error: " \
|
||||
<< hipGetErrorString(err) \
|
||||
<< " at " << __LINE__ << "\n"; \
|
||||
} \
|
||||
}
|
||||
|
||||
__global__ void zeroAddr(int* pointer) {
|
||||
*pointer = 0;
|
||||
}
|
||||
|
||||
__global__ void fillAddr(int* pointer) {
|
||||
*pointer = 42;
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
|
||||
int currentDev = 0;
|
||||
|
||||
// Step 1: Check virtual memory management support on device 0
|
||||
int vmm = 0;
|
||||
HIP_CHECK(
|
||||
hipDeviceGetAttribute(
|
||||
&vmm, hipDeviceAttributeVirtualMemoryManagementSupported, currentDev
|
||||
)
|
||||
);
|
||||
|
||||
std::cout << "Virtual memory management support value: " << vmm << std::endl;
|
||||
|
||||
if (vmm == 0) {
|
||||
std::cout << "GPU 0 doesn't support virtual memory management.";
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Size of memory to allocate
|
||||
size_t size = 4 * 1024;
|
||||
|
||||
// Step 2: Allocate physical memory
|
||||
hipMemGenericAllocationHandle_t allocHandle;
|
||||
hipMemAllocationProp prop = {};
|
||||
prop.type = hipMemAllocationTypePinned;
|
||||
prop.location.type = hipMemLocationTypeDevice;
|
||||
prop.location.id = currentDev;
|
||||
size_t granularity = 0;
|
||||
HIP_CHECK(
|
||||
hipMemGetAllocationGranularity(
|
||||
&granularity,
|
||||
&prop,
|
||||
hipMemAllocationGranularityMinimum));
|
||||
size_t padded_size = ROUND_UP(size, granularity);
|
||||
HIP_CHECK(hipMemCreate(&allocHandle, padded_size * 2, &prop, 0));
|
||||
|
||||
// Step 3: Reserve a virtual memory address range
|
||||
void* virtualPointer = nullptr;
|
||||
HIP_CHECK(hipMemAddressReserve(&virtualPointer, padded_size, granularity, nullptr, 0));
|
||||
|
||||
// Step 4: Map the physical memory to the virtual address range
|
||||
HIP_CHECK(hipMemMap(virtualPointer, padded_size, 0, allocHandle, 0));
|
||||
|
||||
// Step 5: Set memory access permission for pointer
|
||||
hipMemAccessDesc accessDesc = {};
|
||||
accessDesc.location.type = hipMemLocationTypeDevice;
|
||||
accessDesc.location.id = currentDev;
|
||||
accessDesc.flags = hipMemAccessFlagsProtReadWrite;
|
||||
|
||||
HIP_CHECK(hipMemSetAccess(virtualPointer, padded_size, &accessDesc, 1));
|
||||
|
||||
// Step 6: Perform memory operation
|
||||
int value = 42;
|
||||
HIP_CHECK(hipMemcpy(virtualPointer, &value, sizeof(int), hipMemcpyHostToDevice));
|
||||
|
||||
int result = 1;
|
||||
HIP_CHECK(hipMemcpy(&result, virtualPointer, sizeof(int), hipMemcpyDeviceToHost));
|
||||
if( result == 42) {
|
||||
std::cout << "Success. Value: " << result << std::endl;
|
||||
} else {
|
||||
std::cout << "Failure. Value: " << result << std::endl;
|
||||
}
|
||||
|
||||
// Step 7: Launch kernels
|
||||
// Launch zeroAddr kernel
|
||||
zeroAddr<<<1, 1>>>((int*)virtualPointer);
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
|
||||
// Check zeroAddr kernel result
|
||||
result = 1;
|
||||
HIP_CHECK(hipMemcpy(&result, virtualPointer, sizeof(int), hipMemcpyDeviceToHost));
|
||||
if( result == 0) {
|
||||
std::cout << "Success. zeroAddr kernel: " << result << std::endl;
|
||||
} else {
|
||||
std::cout << "Failure. zeroAddr kernel: " << result << std::endl;
|
||||
}
|
||||
|
||||
// Launch fillAddr kernel
|
||||
fillAddr<<<1, 1>>>((int*)virtualPointer);
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
|
||||
// Check fillAddr kernel result
|
||||
result = 1;
|
||||
HIP_CHECK(hipMemcpy(&result, virtualPointer, sizeof(int), hipMemcpyDeviceToHost));
|
||||
if( result == 42) {
|
||||
std::cout << "Success. fillAddr kernel: " << result << std::endl;
|
||||
} else {
|
||||
std::cout << "Failure. fillAddr kernel: " << result << std::endl;
|
||||
}
|
||||
|
||||
// Step 8: Cleanup
|
||||
HIP_CHECK(hipMemUnmap(virtualPointer, padded_size));
|
||||
HIP_CHECK(hipMemRelease(allocHandle));
|
||||
HIP_CHECK(hipMemAddressFree(virtualPointer, padded_size));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Virtual aliases
|
||||
================================================================================
|
||||
|
||||
Virtual aliases are multiple virtual memory addresses mapping to the same
|
||||
physical memory on the GPU. When this occurs, different threads, processes, or memory
|
||||
allocations to access shared physical memory through different virtual
|
||||
addresses on different devices.
|
||||
|
||||
Multiple virtual memory mappings can be created using multiple calls to
|
||||
:cpp:func:`hipMemMap` on the same memory allocation.
|
||||
|
||||
.. note::
|
||||
|
||||
RDNA cards may not produce correct results, if users access two different
|
||||
virtual addresses that map to the same physical address. In this case, the
|
||||
L1 data caches will be incoherent due to the virtual-to-physical aliasing.
|
||||
These GPUs will produce correct results if users access virtual-to-physical
|
||||
aliases using volatile pointers.
|
||||
|
||||
NVIDIA GPUs require special fences to produce correct results when
|
||||
using virtual aliases.
|
||||
|
||||
In the following code block, the kernels input device pointers are virtual
|
||||
aliases of the same memory allocation:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
__global__ void updateBoth(int* pointerA, int* pointerB) {
|
||||
// May produce incorrect results on RDNA and NVIDIA cards.
|
||||
*pointerA = 0;
|
||||
*pointerB = 42;
|
||||
}
|
||||
|
||||
__global__ void updateBoth_v2(volatile int* pointerA, volatile int* pointerB) {
|
||||
// May produce incorrect results on NVIDIA cards.
|
||||
*pointerA = 0;
|
||||
*pointerB = 42;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,420 @@
|
||||
.. meta::
|
||||
:description: This chapter describes how to use multiple devices on one host.
|
||||
:keywords: ROCm, HIP, multi-device, multiple, GPUs, devices
|
||||
|
||||
.. _multi-device:
|
||||
|
||||
*******************************************************************************
|
||||
Multi-device management
|
||||
*******************************************************************************
|
||||
|
||||
Device enumeration
|
||||
===============================================================================
|
||||
|
||||
Device enumeration involves identifying all the available GPUs connected to the
|
||||
host system. A single host machine can have multiple GPUs, each with its own
|
||||
unique identifier. By listing these devices, you can decide which GPU to use
|
||||
for computation. The host queries the system to count and list all connected
|
||||
GPUs that support the chosen ``HIP_PLATFORM``, ensuring that the application
|
||||
can leverage the full computational power available. Typically, applications
|
||||
list devices and their properties for deployment planning, and also make
|
||||
dynamic selections during runtime to ensure optimal performance.
|
||||
|
||||
If the application does not define a specific GPU, device 0 is selected.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
int deviceCount;
|
||||
hipGetDeviceCount(&deviceCount);
|
||||
std::cout << "Number of devices: " << deviceCount << std::endl;
|
||||
|
||||
for (int deviceId = 0; deviceId < deviceCount; ++deviceId)
|
||||
{
|
||||
hipDeviceProp_t deviceProp;
|
||||
hipGetDeviceProperties(&deviceProp, deviceId);
|
||||
std::cout << "Device " << deviceId << std::endl << " Properties:" << std::endl;
|
||||
std::cout << " Name: " << deviceProp.name << std::endl;
|
||||
std::cout << " Total Global Memory: " << deviceProp.totalGlobalMem / (1024 * 1024) << " MiB" << std::endl;
|
||||
std::cout << " Shared Memory per Block: " << deviceProp.sharedMemPerBlock / 1024 << " KiB" << std::endl;
|
||||
std::cout << " Registers per Block: " << deviceProp.regsPerBlock << std::endl;
|
||||
std::cout << " Warp Size: " << deviceProp.warpSize << std::endl;
|
||||
std::cout << " Max Threads per Block: " << deviceProp.maxThreadsPerBlock << std::endl;
|
||||
std::cout << " Max Threads per Multiprocessor: " << deviceProp.maxThreadsPerMultiProcessor << std::endl;
|
||||
std::cout << " Number of Multiprocessors: " << deviceProp.multiProcessorCount << std::endl;
|
||||
std::cout << " Max Threads Dimensions: ["
|
||||
<< deviceProp.maxThreadsDim[0] << ", "
|
||||
<< deviceProp.maxThreadsDim[1] << ", "
|
||||
<< deviceProp.maxThreadsDim[2] << "]" << std::endl;
|
||||
std::cout << " Max Grid Size: ["
|
||||
<< deviceProp.maxGridSize[0] << ", "
|
||||
<< deviceProp.maxGridSize[1] << ", "
|
||||
<< deviceProp.maxGridSize[2] << "]" << std::endl;
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
.. _multi_device_selection:
|
||||
|
||||
Device selection
|
||||
===============================================================================
|
||||
|
||||
Once you have enumerated the available GPUs, the next step is to select a
|
||||
specific device for computation. This involves setting the active GPU that will
|
||||
execute subsequent operations. This step is crucial in multi-GPU systems where
|
||||
different GPUs might have different capabilities or workloads. By selecting the
|
||||
appropriate device, you ensure that the computational tasks are directed to the
|
||||
correct GPU, optimizing performance and resource utilization.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <iostream>
|
||||
|
||||
#define HIP_CHECK(expression) \
|
||||
{ \
|
||||
const hipError_t status = expression; \
|
||||
if (status != hipSuccess) { \
|
||||
std::cerr << "HIP error " << status \
|
||||
<< ": " << hipGetErrorString(status) \
|
||||
<< " at " << __FILE__ << ":" \
|
||||
<< __LINE__ << std::endl; \
|
||||
exit(status); \
|
||||
} \
|
||||
}
|
||||
|
||||
__global__ void simpleKernel(double *data)
|
||||
{
|
||||
int idx = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
data[idx] = idx * 2.0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
double* deviceData0;
|
||||
double* deviceData1;
|
||||
size_t size = 1024 * sizeof(*deviceData0);
|
||||
|
||||
int deviceId0 = 0;
|
||||
int deviceId1 = 1;
|
||||
|
||||
// Set device 0 and perform operations
|
||||
HIP_CHECK(hipSetDevice(deviceId0)); // Set device 0 as current
|
||||
HIP_CHECK(hipMalloc(&deviceData0, size)); // Allocate memory on device 0
|
||||
simpleKernel<<<1000, 128>>>(deviceData0); // Launch kernel on device 0
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
|
||||
// Set device 1 and perform operations
|
||||
HIP_CHECK(hipSetDevice(deviceId1)); // Set device 1 as current
|
||||
HIP_CHECK(hipMalloc(&deviceData1, size)); // Allocate memory on device 1
|
||||
simpleKernel<<<1000, 128>>>(deviceData1); // Launch kernel on device 1
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
|
||||
// Copy result from device 0
|
||||
double hostData0[1024];
|
||||
HIP_CHECK(hipSetDevice(deviceId0));
|
||||
HIP_CHECK(hipMemcpy(hostData0, deviceData0, size, hipMemcpyDeviceToHost));
|
||||
|
||||
// Copy result from device 1
|
||||
double hostData1[1024];
|
||||
HIP_CHECK(hipSetDevice(deviceId1));
|
||||
HIP_CHECK(hipMemcpy(hostData1, deviceData1, size, hipMemcpyDeviceToHost));
|
||||
|
||||
// Display results from both devices
|
||||
std::cout << "Device 0 data: " << hostData0[0] << std::endl;
|
||||
std::cout << "Device 1 data: " << hostData1[0] << std::endl;
|
||||
|
||||
// Free device memory
|
||||
HIP_CHECK(hipFree(deviceData0));
|
||||
HIP_CHECK(hipFree(deviceData1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Stream and event behavior
|
||||
===============================================================================
|
||||
|
||||
In a multi-device system, streams and events are essential for efficient
|
||||
parallel computation and synchronization. Streams enable asynchronous task
|
||||
execution, allowing multiple devices to process data concurrently without
|
||||
blocking one another. Events provide a mechanism for synchronizing operations
|
||||
across streams and devices, ensuring that tasks on one device are completed
|
||||
before dependent tasks on another device begin. This coordination prevents race
|
||||
conditions and optimizes data flow in multi-GPU systems. Together, streams and
|
||||
events maximize performance by enabling parallel execution, load balancing, and
|
||||
effective resource utilization across heterogeneous hardware.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <iostream>
|
||||
|
||||
__global__ void simpleKernel(double *data)
|
||||
{
|
||||
int idx = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
data[idx] = idx * 2.0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int numDevices;
|
||||
hipGetDeviceCount(&numDevices);
|
||||
|
||||
if (numDevices < 2) {
|
||||
std::cerr << "This example requires at least two GPUs." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
double *deviceData0, *deviceData1;
|
||||
size_t size = 1024 * sizeof(*deviceData0);
|
||||
|
||||
// Create streams and events for each device
|
||||
hipStream_t stream0, stream1;
|
||||
hipEvent_t startEvent0, stopEvent0, startEvent1, stopEvent1;
|
||||
|
||||
// Initialize device 0
|
||||
hipSetDevice(0);
|
||||
hipStreamCreate(&stream0);
|
||||
hipEventCreate(&startEvent0);
|
||||
hipEventCreate(&stopEvent0);
|
||||
hipMalloc(&deviceData0, size);
|
||||
|
||||
// Initialize device 1
|
||||
hipSetDevice(1);
|
||||
hipStreamCreate(&stream1);
|
||||
hipEventCreate(&startEvent1);
|
||||
hipEventCreate(&stopEvent1);
|
||||
hipMalloc(&deviceData1, size);
|
||||
|
||||
// Record the start event on device 0
|
||||
hipSetDevice(0);
|
||||
hipEventRecord(startEvent0, stream0);
|
||||
|
||||
// Launch the kernel asynchronously on device 0
|
||||
simpleKernel<<<1000, 128, 0, stream0>>>(deviceData0);
|
||||
|
||||
// Record the stop event on device 0
|
||||
hipEventRecord(stopEvent0, stream0);
|
||||
|
||||
// Wait for the stop event on device 0 to complete
|
||||
hipEventSynchronize(stopEvent0);
|
||||
|
||||
// Record the start event on device 1
|
||||
hipSetDevice(1);
|
||||
hipEventRecord(startEvent1, stream1);
|
||||
|
||||
// Launch the kernel asynchronously on device 1
|
||||
simpleKernel<<<1000, 128, 0, stream1>>>(deviceData1);
|
||||
|
||||
// Record the stop event on device 1
|
||||
hipEventRecord(stopEvent1, stream1);
|
||||
|
||||
// Wait for the stop event on device 1 to complete
|
||||
hipEventSynchronize(stopEvent1);
|
||||
|
||||
// Calculate elapsed time between the events for both devices
|
||||
float milliseconds0 = 0, milliseconds1 = 0;
|
||||
hipEventElapsedTime(&milliseconds0, startEvent0, stopEvent0);
|
||||
hipEventElapsedTime(&milliseconds1, startEvent1, stopEvent1);
|
||||
|
||||
std::cout << "Elapsed time on GPU 0: " << milliseconds0 << " ms" << std::endl;
|
||||
std::cout << "Elapsed time on GPU 1: " << milliseconds1 << " ms" << std::endl;
|
||||
|
||||
// Cleanup for device 0
|
||||
hipSetDevice(0);
|
||||
hipEventDestroy(startEvent0);
|
||||
hipEventDestroy(stopEvent0);
|
||||
hipStreamSynchronize(stream0);
|
||||
hipStreamDestroy(stream0);
|
||||
hipFree(deviceData0);
|
||||
|
||||
// Cleanup for device 1
|
||||
hipSetDevice(1);
|
||||
hipEventDestroy(startEvent1);
|
||||
hipEventDestroy(stopEvent1);
|
||||
hipStreamSynchronize(stream1);
|
||||
hipStreamDestroy(stream1);
|
||||
hipFree(deviceData1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Peer-to-peer memory access
|
||||
===============================================================================
|
||||
|
||||
In multi-GPU systems, peer-to-peer memory access enables one GPU to directly
|
||||
read or write to the memory of another GPU. This capability reduces data
|
||||
transfer times by allowing GPUs to communicate directly without involving the
|
||||
host. Enabling peer-to-peer access can significantly improve the performance of
|
||||
applications that require frequent data exchange between GPUs, as it eliminates
|
||||
the need to transfer data through the host memory.
|
||||
|
||||
By adding peer-to-peer access to the example referenced in
|
||||
:ref:`multi_device_selection`, data can be copied between devices:
|
||||
|
||||
.. tab-set::
|
||||
|
||||
.. tab-item:: with peer-to-peer
|
||||
|
||||
.. code-block:: cpp
|
||||
:emphasize-lines: 31-37, 51-55
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <iostream>
|
||||
|
||||
#define HIP_CHECK(expression) \
|
||||
{ \
|
||||
const hipError_t status = expression; \
|
||||
if (status != hipSuccess) { \
|
||||
std::cerr << "HIP error " << status \
|
||||
<< ": " << hipGetErrorString(status) \
|
||||
<< " at " << __FILE__ << ":" \
|
||||
<< __LINE__ << std::endl; \
|
||||
exit(status); \
|
||||
} \
|
||||
}
|
||||
|
||||
__global__ void simpleKernel(double *data)
|
||||
{
|
||||
int idx = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
data[idx] = idx * 2.0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
double* deviceData0;
|
||||
double* deviceData1;
|
||||
size_t size = 1024 * sizeof(*deviceData0);
|
||||
|
||||
int deviceId0 = 0;
|
||||
int deviceId1 = 1;
|
||||
|
||||
// Enable peer access to the memory (allocated and future) on the peer device.
|
||||
// Ensure the device is active before enabling peer access.
|
||||
hipSetDevice(deviceId0);
|
||||
hipDeviceEnablePeerAccess(deviceId1, 0);
|
||||
|
||||
hipSetDevice(deviceId1);
|
||||
hipDeviceEnablePeerAccess(deviceId0, 0);
|
||||
|
||||
// Set device 0 and perform operations
|
||||
HIP_CHECK(hipSetDevice(deviceId0)); // Set device 0 as current
|
||||
HIP_CHECK(hipMalloc(&deviceData0, size)); // Allocate memory on device 0
|
||||
simpleKernel<<<1000, 128>>>(deviceData0); // Launch kernel on device 0
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
|
||||
// Set device 1 and perform operations
|
||||
HIP_CHECK(hipSetDevice(deviceId1)); // Set device 1 as current
|
||||
HIP_CHECK(hipMalloc(&deviceData1, size)); // Allocate memory on device 1
|
||||
simpleKernel<<<1000, 128>>>(deviceData1); // Launch kernel on device 1
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
|
||||
// Use peer-to-peer access
|
||||
hipSetDevice(deviceId0);
|
||||
|
||||
// Now device 0 can access memory allocated on device 1
|
||||
hipMemcpy(deviceData0, deviceData1, size, hipMemcpyDeviceToDevice);
|
||||
|
||||
// Copy result from device 0
|
||||
double hostData0[1024];
|
||||
HIP_CHECK(hipSetDevice(deviceId0));
|
||||
HIP_CHECK(hipMemcpy(hostData0, deviceData0, size, hipMemcpyDeviceToHost));
|
||||
|
||||
// Copy result from device 1
|
||||
double hostData1[1024];
|
||||
HIP_CHECK(hipSetDevice(deviceId1));
|
||||
HIP_CHECK(hipMemcpy(hostData1, deviceData1, size, hipMemcpyDeviceToHost));
|
||||
|
||||
// Display results from both devices
|
||||
std::cout << "Device 0 data: " << hostData0[0] << std::endl;
|
||||
std::cout << "Device 1 data: " << hostData1[0] << std::endl;
|
||||
|
||||
// Free device memory
|
||||
HIP_CHECK(hipFree(deviceData0));
|
||||
HIP_CHECK(hipFree(deviceData1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
.. tab-item:: without peer-to-peer
|
||||
|
||||
.. code-block:: cpp
|
||||
:emphasize-lines: 43-49, 53, 58
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <iostream>
|
||||
|
||||
#define HIP_CHECK(expression) \
|
||||
{ \
|
||||
const hipError_t status = expression; \
|
||||
if (status != hipSuccess) { \
|
||||
std::cerr << "HIP error " << status \
|
||||
<< ": " << hipGetErrorString(status) \
|
||||
<< " at " << __FILE__ << ":" \
|
||||
<< __LINE__ << std::endl; \
|
||||
exit(status); \
|
||||
} \
|
||||
}
|
||||
|
||||
__global__ void simpleKernel(double *data)
|
||||
{
|
||||
int idx = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
data[idx] = idx * 2.0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
double* deviceData0;
|
||||
double* deviceData1;
|
||||
size_t size = 1024 * sizeof(*deviceData0);
|
||||
|
||||
int deviceId0 = 0;
|
||||
int deviceId1 = 1;
|
||||
|
||||
// Set device 0 and perform operations
|
||||
HIP_CHECK(hipSetDevice(deviceId0)); // Set device 0 as current
|
||||
HIP_CHECK(hipMalloc(&deviceData0, size)); // Allocate memory on device 0
|
||||
simpleKernel<<<1000, 128>>>(deviceData0); // Launch kernel on device 0
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
|
||||
// Set device 1 and perform operations
|
||||
HIP_CHECK(hipSetDevice(deviceId1)); // Set device 1 as current
|
||||
HIP_CHECK(hipMalloc(&deviceData1, size)); // Allocate memory on device 1
|
||||
simpleKernel<<<1000, 128>>>(deviceData1); // Launch kernel on device 1
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
|
||||
// Attempt to use deviceData0 on device 1 (This will not work as deviceData0 is allocated on device 0)
|
||||
HIP_CHECK(hipSetDevice(deviceId1));
|
||||
hipError_t err = hipMemcpy(deviceData1, deviceData0, size, hipMemcpyDeviceToDevice); // This should fail
|
||||
if (err != hipSuccess)
|
||||
{
|
||||
std::cout << "Error: Cannot access deviceData0 from device 1, deviceData0 is on device 0" << std::endl;
|
||||
}
|
||||
|
||||
// Copy result from device 0
|
||||
double hostData0[1024];
|
||||
HIP_CHECK(hipSetDevice(deviceId0));
|
||||
HIP_CHECK(hipMemcpy(hostData0, deviceData0, size, hipMemcpyDeviceToHost));
|
||||
|
||||
// Copy result from device 1
|
||||
double hostData1[1024];
|
||||
HIP_CHECK(hipSetDevice(deviceId1));
|
||||
HIP_CHECK(hipMemcpy(hostData1, deviceData1, size, hipMemcpyDeviceToHost));
|
||||
|
||||
// Display results from both devices
|
||||
std::cout << "Device 0 data: " << hostData0[0] << std::endl;
|
||||
std::cout << "Device 1 data: " << hostData1[0] << std::endl;
|
||||
|
||||
// Free device memory
|
||||
HIP_CHECK(hipFree(deviceData0));
|
||||
HIP_CHECK(hipFree(deviceData1));
|
||||
|
||||
return 0;
|
||||
}
|
||||