Skip to content

Commit 61f2f9a

Browse files
authored
Merge branch 'master' into patch-6
2 parents 10824e7 + 70b5cbd commit 61f2f9a

File tree

1 file changed

+39
-14
lines changed

1 file changed

+39
-14
lines changed

affinity/cpp-20/d0796r2.md

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,16 @@
1414

1515
# Changelog
1616

17+
### P0796r2 (RAP)
18+
19+
* Introduced a free function for retrieving the execution resource underlying the current thread of execution.
20+
1721
### P0796r1 (JAX)
1822

1923
* Introduce proposed wording.
2024
* Based on feedback from SG1, introduce a pair-wise interface for querying the relative affinity between execution resources.
2125
* Introduce an interface for retrieving an allocator or polymorphic memory resource.
22-
* Based on feedback from SG1, remove requirement for a hierarchical system topology structure, which doesn't require a root resouce.
26+
* Based on feedback from SG1, remove requirement for a hierarchical system topology structure, which doesn't require a root resource.
2327

2428
### P0796r0 (ABQ)
2529

@@ -180,12 +184,12 @@ An `execution_resource` is a lightweight structure which acts as an identifier t
180184
181185
### System topology
182186
183-
The system topology is made up of a number of system-level `execution_resource`s, which can be queried through `this_system::resource` which returns a `std::vector`. A run-time library may initialize the `execution_resources` available within the system dynamically. However, this must be done before `main` is called, given that after that point, the system topology may not change.
187+
The system topology is made up of a number of system-level `execution_resource`s, which can be queried through `this_system::get_resources` which returns a `std::vector`. A run-time library may initialize the `execution_resource`s available within the system dynamically. However, this must be done before `main` is called, given that after that point, the system topology may not change.
184188
185189
Below *(Listing 2)* is an example of iterating over the system-level resources and printing out their capabilities.
186190
187191
```cpp
188-
for (auto res : execution::this_system::resources()) {
192+
for (auto res : execution::this_system::get_resources()) {
189193
std::cout << res.name() `\n`;
190194
std::cout << res.can_place_memory() << `\n`;
191195
std::cout << res.can_place_agents() << `\n`;
@@ -194,14 +198,18 @@ for (auto res : execution::this_system::resources()) {
194198
```
195199
*Listing 2: Example of querying all the system level execution resources*
196200

201+
### Current resource
202+
203+
The `execution_resource` which underlies the current thread of execution can be queried through `this_thread::get_resource`.
204+
197205
### Querying relative affinity
198206

199207
The `affinity_query` class template provides an abstraction for a relative affinity value between two `execution_resource`s. This value depends on a particular `affinity_operation` and `affinity_metric`. As a result, the `affinity_query` is templated on `affinity_operation` and `affinity_metric`, and is constructed from two `execution_resource`s. An `affinity_query` is not meant to be meaningful on its own. Instead, users are meant to compare two queries with comparison operators, in order to get a relative magnitude of affinity. If necessary, the value of an `affinity_query` can also be queried through `native_affinity`, though the return value of this is implementation defined.
200208

201209
Below *(listing 3)* is an example of how to query the relative affinity between two `execution_resource`s.
202210

203211
```cpp
204-
auto systemLevelResources = execution::this_system::resources();
212+
auto systemLevelResources = execution::this_system::get_resources();
205213
auto memberResources = systemLevelResources.resources();
206214

207215
auto relativeLatency01 = execution::affinity_query<execution::affinity_operation::read,
@@ -223,15 +231,15 @@ The `execution_context` class provides an abstraction for managing a number of l
223231
Below *(Listing 4)* is an example of how this extended interface could be used to construct an *execution context* from an *execution resource* which is retrieved from the *system’s resource topology*. Once an *execution context* is constructed it can then still be queried for its *execution resource*, and that *execution resource* can be further partitioned.
224232

225233
```cpp
226-
auto &resources = execution::this_system::resources();
234+
auto &resources = execution::this_system::get_resources();
227235

228236
execution::execution_context execContext(resources[0]);
229237

230-
auto &systelLevelResource = execContext.resource();
238+
auto &systemLevelResource = execContext.resource();
231239

232240
// resource[0] should be equal to execResource
233241

234-
for (auto res : systelLevelResource.resources()) {
242+
for (auto res : systemLevelResource.resources()) {
235243
std::cout << res.name() << `\n`;
236244
}
237245
```
@@ -242,11 +250,11 @@ for (auto res : systelLevelResource.resources()) {
242250
When creating an `execution_context` from a given `execution_resource`, the executors and allocators associated with it are bound to that `execution_resource`. For example, when creating an `execution_resource` from a CPU socket resource, all executors associated with the given socket will spawn execution agents with affinity to the socket partition of the system *(Listing 5)*.
243251
244252
```cpp
245-
auto cList = std::execution::this_system::resources();
253+
auto cList = std::execution::this_system::get_resources();
246254
// FindASocketResource is a user-defined function that finds a
247255
// resource that is a CPU socket in the given resource list
248256
auto& socket = findASocketResource(cList);
249-
execution_contexteC{socket} // Associated with the socket
257+
execution_contextC{socket} // Associated with the socket
250258
auto executor = eC.executor(); // By transitivity, associated with the socket too
251259
auto socketAllocator = eC.allocator(); // Retrieve an allocator to the closest memory node
252260
std::vector<int, decltype(socketAllocator)> v1(100, socketAllocator);
@@ -343,13 +351,20 @@ If a particular policy or algorithm requires to access placement information, th
343351

344352
};
345353

354+
} // execution
355+
346356
/* This system */
347357

348358
namespace this_system {
349359
std::vector<execution_resource> resources() noexcept;
350360
}
351361

352-
} // execution
362+
/* This thread */
363+
364+
namespace this_thread {
365+
std::experimental::execution::execution_resource get_resource() noexcept;
366+
}
367+
353368
} // experimental
354369
} // std
355370

@@ -496,7 +511,7 @@ The `affinity_query` class template provides an abstraction for a relative affin
496511
friend expected<size_t, error_type> operator>=(const affinity_query&, const affinity_query&);
497512

498513
*Returns:* An `expected<size_t, error_type>` where,
499-
* if the affinity query was succesful, the value of type `size_t` represents the magnitude of the relative affinity;
514+
* if the affinity query was successful, the value of type `size_t` represents the magnitude of the relative affinity;
500515
* if the affinity query was not successful, the error is an error of type `error_type` which represents the reason for affinity query failed.
501516

502517
> [*Note:* An affinity query is permitted to fail if affinity between the two execution resources cannot be calculated for any reason, such as the resources are of different vendors or communication between the resources is not possible. *--end note*]
@@ -505,16 +520,26 @@ The `affinity_query` class template provides an abstraction for a relative affin
505520
506521
## Free functions
507522

508-
The free function `this_system::resources` is provided for retrieving the `execution_resource`s which encapsulate the hardware platforms available within the system. We refer to these resources as the *system level resources*.
523+
### `this_system::get_resources`
524+
525+
The free function `this_system::get_resources` is provided for retrieving the `execution_resource`s which encapsulate the hardware platforms available within the system. We refer to these resources as the *system level resources*.
509526

510527
std::vector<execution_resource> resources() noexcept;
511528

512529
*Returns:* An `std::vector` containing all *system level resources*.
513530

514-
*Requires:* If `this_system::resources().size() > 0`, `this_system::resources()[0]` be the `execution_resource` use by `std::thread`. The value returned by `this_system::resources()` be the same at any point after the invocation of `main`.
531+
*Requires:* If `this_system::get_resources().size() > 0`, `this_system::get_resources()[0]` be the `execution_resource` use by `std::thread`. The value returned by `this_system::get_resources()` be the same at any point after the invocation of `main`.
515532

516533
> [*Note:* Returning a `std::vector` allows users to potentially manipulate the container of `execution_resource`s after it is returned. We may want to replace this at a later date with an alternative type which is more restrictive, such as a range or span. *--end note*]
517534
535+
### `this_thread::get_resource`
536+
537+
The free function `this_thread::get_resource` is provided for retrieving the `execution_resource` underlying the current thread of execution.
538+
539+
std::experimental::execution::execution_resource get_resource() noexcept;
540+
541+
*Returns:* The `execution_resource` underlying the current thread of execution.
542+
518543
# Future Work
519544

520545
## Migrating data from memory allocated in one partition to another
@@ -545,7 +570,7 @@ We may wish to mirror the design of the executors proposal and have a generic qu
545570

546571
## Dynamic topology discovery
547572

548-
The current proposal requires that all `execution_resource`s are initialized before `main` is called. This therefore does not permit an `execution_resource` to become available or go off-line at run time. We may wish to support this in the future, however this is outside of the scope of this paper.
573+
The current proposal requires that all `execution_resource`s are initialized before `main` is called. This therefore does not permit an `execution_resource` to become available or go off-line at run time. We may wish to support this in the future, however this is outside of the scope of this paper at the moment.
549574

550575
| Straw Poll |
551576
|------------|

0 commit comments

Comments
 (0)