@@ -60,28 +60,43 @@ static const bool UseCopyEngineForD2DCopy = [] {
60
60
return (CopyEngineForD2DCopy && (std::stoi (CopyEngineForD2DCopy) != 0 ));
61
61
}();
62
62
63
- // TODO: Add support for non-zero values of SYCL_PI_LEVEL_ZERO_USE_COPY_ENGINE
64
- static const bool CopyEngineRequested = [] {
65
- const char *CopyEngine = std::getenv ( " SYCL_PI_LEVEL_ZERO_USE_COPY_ENGINE " );
66
- bool UseCopyEngine = (!CopyEngine || ((CopyEngine[ 1 ] == ' \0 ' ) &&
67
- ( std::stoi (CopyEngine) != 0 )));
68
- return UseCopyEngine;
69
- }();
70
-
63
+ // SYCL_PI_LEVEL_ZERO_USE_COPY_ENGINE can be set to an integer value, or
64
+ // a pair of integer values of the form "lower_index:upper_index".
65
+ // Here, the indices point to copy engines in a list of all available copy
66
+ // engines.
67
+ // This functions returns this pair of indices.
68
+ // If the user specifies only a single integer, a value of 0 indicates that
69
+ // the copy engines will not be used at all. A value of 1 indicates that all
70
+ // available copy engines can be used.
71
71
static const std::pair<int , int > getRangeOfAllowedCopyEngines = [] {
72
- const char * CopyEngineRange =
72
+ std::string CopyEngineRange =
73
73
std::getenv (" SYCL_PI_LEVEL_ZERO_USE_COPY_ENGINE" );
74
- if (CopyEngineRange && (CopyEngineRange[1 ] == ' \0 ' )) {
75
- if (CopyEngineRange[0 ] == ' 0' )
76
- return std::pair<int , int >(-1 , -1 );
74
+ // If the environment variable is not set, all available copy engines can be
75
+ // used.
76
+ if (CopyEngineRange.empty ()) {
77
+ return std::pair<int , int >(0 , INT_MAX);
78
+ }
79
+ // Environment variable can be a single integer or a pair of integers
80
+ // separated by ":"
81
+ auto pos = CopyEngineRange.find (" :" );
82
+ if (pos == std::string::npos) {
83
+ bool UseCopyEngine = (std::stoi (CopyEngineRange) != 0 );
84
+ if (UseCopyEngine)
85
+ return std::pair<int , int >(0 , INT_MAX); // All copy engines can be used.
77
86
else
78
- return std::pair<int , int >(0 , 8 );
87
+ return std::pair<int , int >(- 1 , - 1 ); // No copy engines will be used.
79
88
}
80
- int LowerCopyEngineIndex = (CopyEngineRange) ? (CopyEngineRange[ 0 ] - ' 0 ' ) : 0 ;
81
- int UpperCopyEngineIndex = (CopyEngineRange) ? (CopyEngineRange[ 2 ] - ' 0 ' ) : 8 ;
89
+ int LowerCopyEngineIndex = std::stoi (CopyEngineRange. substr ( 0 , pos)) ;
90
+ int UpperCopyEngineIndex = std::stoi (CopyEngineRange. substr (pos + 1 )) ;
82
91
return std::pair<int , int >(LowerCopyEngineIndex, UpperCopyEngineIndex);
83
92
}();
84
93
94
+ static const bool CopyEngineRequested = [] {
95
+ const char *CopyEngine = std::getenv (" SYCL_PI_LEVEL_ZERO_USE_COPY_ENGINE" );
96
+ bool UseCopyEngine = (!CopyEngine || (std::stoi (CopyEngine) != 0 ));
97
+ return UseCopyEngine;
98
+ }();
99
+
85
100
// This class encapsulates actions taken along with a call to Level Zero API.
86
101
class ZeCall {
87
102
private:
@@ -1077,13 +1092,15 @@ _pi_queue::getZeCopyCommandQueue(int *CopyQueueIndex,
1077
1092
LowerCopyQueueIndex = std::max (0 , LowerCopyQueueIndex);
1078
1093
UpperCopyQueueIndex = std::min (UpperCopyQueueIndex, n - 1 );
1079
1094
1080
- // Return nullptr when no copy command queues are available
1081
- if (n == 0 ) {
1095
+ // Return nullptr when no copy command queues are allowed to be used or if
1096
+ // no copy command queues are available.
1097
+ if ((LowerCopyQueueIndex > UpperCopyQueueIndex) || (n == 0 )) {
1082
1098
if (CopyQueueGroupIndex)
1083
1099
*CopyQueueGroupIndex = -1 ;
1084
1100
*CopyQueueIndex = -1 ;
1085
1101
return nullptr ;
1086
1102
}
1103
+
1087
1104
// If there is only one copy queue, it is the main copy queue, which is the
1088
1105
// first, and only entry in ZeCopyCommandQueues.
1089
1106
if (n == 1 ) {
@@ -1096,7 +1113,8 @@ _pi_queue::getZeCopyCommandQueue(int *CopyQueueIndex,
1096
1113
1097
1114
// Round robin logic is used here to access copy command queues.
1098
1115
// Initial value of LastUsedCopyCommandQueueIndex is -1.
1099
- // So, the round robin logic will start its access at 0th queue.
1116
+ // So, the round robin logic will start its access at 'LowerCopyQueueIndex'
1117
+ // queue.
1100
1118
// TODO: In this implementation, all the copy engines (main and link)
1101
1119
// have equal priority. It is expected that main copy engine will be
1102
1120
// advantageous for H2D and D2H copies, whereas the link copy engines will
@@ -2596,11 +2614,9 @@ pi_result piQueueCreate(pi_context Context, pi_device Device,
2596
2614
&ZeCommandQueueDesc, // TODO: translate properties
2597
2615
&ZeComputeCommandQueue));
2598
2616
2599
- // Create additional queues to link copy engines and push them into
2600
- // ZeCopyCommandQueues vector.
2601
2617
std::vector<ze_command_queue_handle_t > ZeCopyCommandQueues;
2602
2618
2603
- // Create second queue to main copy engine
2619
+ // Create queue to main copy engine
2604
2620
ze_command_queue_handle_t ZeMainCopyCommandQueue = nullptr ;
2605
2621
if (Device->hasMainCopyEngine ()) {
2606
2622
zePrint (" NOTE: Main Copy Engine ZeCommandQueueDesc.ordinal = %d, "
@@ -2618,6 +2634,8 @@ pi_result piQueueCreate(pi_context Context, pi_device Device,
2618
2634
}
2619
2635
PI_ASSERT (Queue, PI_INVALID_QUEUE);
2620
2636
2637
+ // Create additional queues to link copy engines and push them into
2638
+ // ZeCopyCommandQueues vector.
2621
2639
if (Device->hasLinkCopyEngine ()) {
2622
2640
auto ZeNumLinkCopyQueues = Device->ZeLinkCopyQueueGroupProperties .numQueues ;
2623
2641
for (uint32_t i = 0 ; i < ZeNumLinkCopyQueues; ++i) {
0 commit comments