@@ -1594,10 +1594,18 @@ struct.
1594
1594
```cpp
1595
1595
namespace sycl::ext::oneapi::experimental {
1596
1596
1597
+ // Types of external memory handles
1598
+ enum class external_mem_handle_type {
1599
+ opaque_fd = 0,
1600
+ win32_nt_handle = 1,
1601
+ win32_nt_dx12_resource = 2,
1602
+ };
1603
+
1597
1604
// Descriptor templated on specific resource type
1598
1605
template <typename ResourceType>
1599
1606
struct external_mem_descriptor {
1600
1607
ResourceType external_resource;
1608
+ external_mem_handle_type handle_type;
1601
1609
size_t size_in_bytes;
1602
1610
};
1603
1611
@@ -1609,9 +1617,13 @@ handle type, `ResourceType`, for their purposes, e.g. `resource_fd` to describe
1609
1617
a POSIX file descriptor resource on Linux systems, or a `resource_win32_handle`
1610
1618
for Windows NT resource handles.
1611
1619
1612
- Once the user populates the `external_mem_descriptor` with the appropriate
1613
- `ResourceType` values, and the size of the external memory in bytes,
1614
- they can then import that memory into SYCL through `import_external_memory`.
1620
+ The user must populate the `external_mem_descriptor` with the appropriate
1621
+ `ResourceType` values, a `handle_type`, and the size of the external memory in
1622
+ bytes, before they can then import that memory into SYCL through
1623
+ `import_external_memory`. Note that some handle types can only be used in
1624
+ combination with certain resource types, for example the `opaque_fd` handle type
1625
+ is only used on Linux systems and is only compatible with the `resource_fd`
1626
+ resource type.
1615
1627
1616
1628
```cpp
1617
1629
namespace sycl::ext::oneapi::experimental {
@@ -1690,16 +1702,32 @@ memory resources handles can take different forms of structure and type
1690
1702
depending on the API and operating system, so do external semaphore resource
1691
1703
handles.
1692
1704
1705
+ It is important to note, that the use of imported external semaphore objects
1706
+ within SYCL has the restriction in that imported external semaphores can only
1707
+ be used in conjuction with SYCL queues that have been constructed with the
1708
+ `property::queue::in_order` property. The semaphore synchronization mechanism
1709
+ is not supported for the default SYCL out-of-order queues. Use of the semaphore
1710
+ synchronization mechanism with SYCL queues which were not constructed with the
1711
+ `queue::in_order` property will result in undefined behaviour.
1712
+
1693
1713
External semaphore import is facilitated through the following proposed
1694
1714
descriptor struct.
1695
1715
1696
1716
```cpp
1697
1717
namespace sycl::ext::oneapi::experimental {
1698
1718
1719
+ // Types of external semaphore handles
1720
+ enum class external_semaphore_handle_type {
1721
+ opaque_fd = 0,
1722
+ win32_nt_handle = 1,
1723
+ win32_nt_dx12_fence = 2,
1724
+ };
1725
+
1699
1726
// Descriptor templated on specific resource type
1700
1727
template <typename ResourceType>
1701
1728
struct external_semaphore_descriptor {
1702
1729
ResourceType external_resource;
1730
+ external_semaphore_handle_type handle_type;
1703
1731
};
1704
1732
1705
1733
}
@@ -1710,9 +1738,12 @@ appropriate handle type, `ResourceType`, for their purposes, e.g. `resource_fd`
1710
1738
to describe a POSIX file descriptor resource on Linux systems, or a
1711
1739
`resource_win32_handle` for Windows NT resource handles.
1712
1740
1713
- Once the user populates the `external_semaphore_descriptor` with the appropriate
1714
- `ResourceType` values, they can then import that semaphore into SYCL through
1715
- `import_external_semaphore`.
1741
+ The user must populate the `external_semaphore_descriptor` with the appropriate
1742
+ `ResourceType` values, and `handle_type`, before they can then import that
1743
+ semaphore into SYCL through `import_external_semaphore`. Note that some handle
1744
+ types can only be used in combination with certain resource types, for example
1745
+ the `opaque_fd` handle type is only used on Linux systems and is only
1746
+ compatible with the `resource_fd` resource type.
1716
1747
1717
1748
```cpp
1718
1749
namespace sycl::ext::oneapi::experimental {
@@ -1728,7 +1759,6 @@ interop_semaphore_handle import_external_semaphore(
1728
1759
externalSemaphoreDescriptor,
1729
1760
const sycl::device &syclDevice,
1730
1761
const sycl::context &syclContext);
1731
- }
1732
1762
1733
1763
template <typename ResourceType>
1734
1764
interop_semaphore_handle import_external_semaphore(
@@ -1739,8 +1769,11 @@ interop_semaphore_handle import_external_semaphore(
1739
1769
```
1740
1770
1741
1771
The resulting `interop_semaphore_handle` can then be used in a SYCL command
1742
- group, to either wait until the semaphore is in the signaled state, or set the
1743
- semaphore to a signaled state.
1772
+ group, to either wait until the semaphore signalled, or signal the semaphore.
1773
+
1774
+ If the type of semaphore imported supports setting the state of discrete
1775
+ semaphore value (the semaphore type is `win32_nt_dx12_fence`), then the user
1776
+ can specify which value the semaphore operation should wait on, or signal.
1744
1777
1745
1778
We propose to extend the SYCL queue and handler classes with semaphore waiting
1746
1779
and signalling operations.
@@ -1754,9 +1787,19 @@ public:
1754
1787
ext::oneapi::experimental::interop_semaphore_handle
1755
1788
interop_semaphore_handle);
1756
1789
1790
+ void ext_oneapi_wait_external_semaphore(
1791
+ ext::oneapi::experimental::interop_semaphore_handle
1792
+ interop_semaphore_handle,
1793
+ uint64_t wait_value);
1794
+
1757
1795
void ext_oneapi_signal_external_semaphore(
1758
1796
ext::oneapi::experimental::interop_semaphore_handle
1759
1797
interop_semaphore_handle);
1798
+
1799
+ void ext_oneapi_signal_external_semaphore(
1800
+ ext::oneapi::experimental::interop_semaphore_handle
1801
+ interop_semaphore_handle,
1802
+ uint64_t signal_value);
1760
1803
};
1761
1804
1762
1805
class queue {
@@ -1773,6 +1816,21 @@ public:
1773
1816
interop_semaphore_handle,
1774
1817
const std::vector<event> &DepEvents);
1775
1818
1819
+ event ext_oneapi_wait_external_semaphore(
1820
+ ext::oneapi::experimental::interop_semaphore_handle
1821
+ interop_semaphore_handle,
1822
+ uint64_t wait_value);
1823
+ event ext_oneapi_wait_external_semaphore(
1824
+ ext::oneapi::experimental::interop_semaphore_handle
1825
+ interop_semaphore_handle,
1826
+ uint64_t wait_value,
1827
+ event DepEvent);
1828
+ event ext_oneapi_wait_external_semaphore(
1829
+ ext::oneapi::experimental::interop_semaphore_handle
1830
+ interop_semaphore_handle,
1831
+ uint64_t wait_value,
1832
+ const std::vector<event> &DepEvents);
1833
+
1776
1834
event ext_oneapi_signal_external_semaphore(
1777
1835
ext::oneapi::experimental::interop_semaphore_handle
1778
1836
interop_semaphore_handle);
@@ -1784,17 +1842,46 @@ public:
1784
1842
ext::oneapi::experimental::interop_semaphore_handle
1785
1843
interop_semaphore_handle,
1786
1844
const std::vector<event> &DepEvents);
1845
+
1846
+ event ext_oneapi_signal_external_semaphore(
1847
+ ext::oneapi::experimental::interop_semaphore_handle
1848
+ interop_semaphore_handle,
1849
+ uint64_t signal_value);
1850
+ event ext_oneapi_signal_external_semaphore(
1851
+ ext::oneapi::experimental::interop_semaphore_handle
1852
+ interop_semaphore_handle,
1853
+ uint64_t signal_value,
1854
+ event DepEvent);
1855
+ event ext_oneapi_signal_external_semaphore(
1856
+ ext::oneapi::experimental::interop_semaphore_handle
1857
+ interop_semaphore_handle,
1858
+ uint64_t signal_value,
1859
+ const std::vector<event> &DepEvents);
1787
1860
};
1788
1861
}
1789
1862
```
1790
1863
1791
- Any operations submitted to the queue after a
1792
- `ext_oneapi_wait_external_semaphore` call will not begin until the imported
1793
- semaphore is in a signaled state.
1864
+ The behaviour of waiting on a semaphore will depend on the type of the
1865
+ semaphore which was imported.
1866
+
1867
+ If the semaphore does not support setting of a discrete state value (the
1868
+ semaphore type is not `win32_nt_dx12_fence`), then any operations submitted to
1869
+ the queue after a `ext_oneapi_wait_external_semaphore` call will not begin
1870
+ until the imported semaphore is in a signalled state. After this, the semaphore
1871
+ will be reset to a non-signalled state.
1872
+
1873
+ If the semaphore does support setting of a discrete state value (the semaphore
1874
+ type is `win32_nt_dx12_fence`), then any operations submitted to the queue
1875
+ after a `ext_oneapi_wait_external_semaphore` call will not begin until the
1876
+ imported semaphore is in a state greater than or equal to the `wait_value`. The
1877
+ state of this type of semaphore will not be altered by the call to
1878
+ `ext_oneapi_wait_external_semaphore`.
1794
1879
1795
1880
When `ext_oneapi_signal_external_semaphore` is called, the external semaphore
1796
- will be set to the signaled state after all commands submitted to the queue
1797
- prior to the `ext_oneapi_signal_external_semaphore` call complete.
1881
+ will either be set to a signalled state, or the state of the semaphore will be
1882
+ set to `signal_value`, depending on the type of semaphore which was imported.
1883
+ This singalling will be done after all commands submitted to the queue prior to
1884
+ the `ext_oneapi_signal_external_semaphore` call complete.
1798
1885
1799
1886
`ext_oneapi_wait_external_semaphore` and `ext_oneapi_signal_external_semaphore`
1800
1887
are non-blocking, asynchronous operations.
@@ -2366,13 +2453,17 @@ int external_output_image_file_descriptor = /* passed from external API */
2366
2453
// Extension: populate external memory descriptors
2367
2454
sycl::ext::oneapi::experimental::external_mem_descriptor<
2368
2455
sycl::ext::oneapi::experimental::resource_fd>
2369
- input_ext_mem_desc{external_input_image_file_descriptor,
2370
- img_size_in_bytes};
2456
+ input_ext_mem_desc{
2457
+ external_input_image_file_descriptor,
2458
+ sycl::ext::oneapi::experimental::external_mem_handle_type::opaque_fd,
2459
+ img_size_in_bytes};
2371
2460
2372
2461
sycl::ext::oneapi::experimental::external_mem_descriptor<
2373
2462
sycl::ext::oneapi::experimental::resource_fd>
2374
- output_ext_mem_desc{external_output_image_file_descriptor,
2375
- img_size_in_bytes};
2463
+ output_ext_mem_desc{
2464
+ external_output_image_file_descriptor,
2465
+ sycl::ext::oneapi::experimental::external_mem_handle_type::opaque_fd,
2466
+ img_size_in_bytes};
2376
2467
2377
2468
// An external API semaphore will signal this semaphore before our SYCL commands
2378
2469
// can begin execution
@@ -2386,11 +2477,13 @@ int done_semaphore_file_descriptor = /* passed from external API */;
2386
2477
// We assume POSIX file descriptor resource types
2387
2478
sycl::ext::oneapi::experimental::external_semaphore_descriptor<
2388
2479
sycl::ext::oneapi::experimental::resource_fd>
2389
- wait_external_semaphore_desc{wait_semaphore_file_descriptor};
2480
+ wait_external_semaphore_desc{wait_semaphore_file_descriptor,
2481
+ sycl::ext::oneapi::experimental::external_semaphore_handle_type::opaque_fd};
2390
2482
2391
2483
sycl::ext::oneapi::experimental::external_semaphore_descriptor<
2392
2484
sycl::ext::oneapi::experimental::resource_fd>
2393
- done_external_semaphore_desc{done_semaphore_file_descriptor};
2485
+ done_external_semaphore_desc{done_semaphore_file_descriptor,
2486
+ sycl::ext::oneapi::experimental::external_semaphore_handle_type::opaque_fd};
2394
2487
2395
2488
try {
2396
2489
// Extension: import external semaphores
@@ -2682,4 +2775,15 @@ These features still need to be handled:
2682
2775
This function is redundant since images don't have a notion
2683
2776
of channel order, only the channel size. Use
2684
2777
`get_num_channels()` instead.
2778
+ |5.11|2024-05-27| - Added `external_mem_handle_type` and
2779
+ `external_semaphore_handle_type` enums. These will allow
2780
+ multiple handle types to be consumed by the same interop API.
2781
+ - Added `handle_type` field to the `external_mem_descriptor`
2782
+ and `external_semaphore_descriptor` structs. This allows
2783
+ multiple handle types to be consumed by the API, such as
2784
+ file descriptors, Windows NT handles, and other handles in
2785
+ the future.
2786
+ - Added semaphore operations which can accept values. These
2787
+ are only supported for certain semaphore types
2788
+ (e.g. `win32_nt_dx12_fence`).
2685
2789
|======================
0 commit comments