Add P2P properties for direct Fabric Link

Related-To: LOCI-3097

Signed-off-by: Joshua Santosh Ranjan <joshua.santosh.ranjan@intel.com>
This commit is contained in:
Joshua Santosh Ranjan 2022-11-29 13:10:43 +00:00 committed by Compute-Runtime-Automation
parent 1e41f7952b
commit 939eb94034
5 changed files with 209 additions and 1 deletions

View File

@ -438,6 +438,48 @@ ze_result_t DeviceImp::getComputeProperties(ze_device_compute_properties_t *pCom
return ZE_RESULT_SUCCESS;
}
void DeviceImp::getP2PPropertiesDirectFabricConnection(DeviceImp *peerDeviceImp,
ze_device_p2p_bandwidth_exp_properties_t *bandwidthPropertiesDesc) {
auto driverHandleImp = static_cast<DriverHandleImp *>(getDriverHandle());
if (driverHandleImp->fabricVertices.empty()) {
driverHandleImp->initializeVertexes();
}
if (this->fabricVertex != nullptr && peerDeviceImp->fabricVertex != nullptr) {
uint32_t directEdgeCount = 0;
driverHandleImp->fabricEdgeGetExp(this->fabricVertex,
peerDeviceImp->fabricVertex,
&directEdgeCount,
nullptr);
if (directEdgeCount > 0) {
std::vector<ze_fabric_edge_handle_t> edges(directEdgeCount);
driverHandleImp->fabricEdgeGetExp(this->fabricVertex,
peerDeviceImp->fabricVertex,
&directEdgeCount,
edges.data());
for (const auto &edge : edges) {
auto fabricEdge = FabricEdge::fromHandle(edge);
ze_fabric_edge_exp_properties_t edgeProperties{};
fabricEdge->getProperties(&edgeProperties);
if (strcmp(edgeProperties.model, "XeLink") == 0) {
bandwidthPropertiesDesc->logicalBandwidth = edgeProperties.bandwidth;
bandwidthPropertiesDesc->physicalBandwidth = edgeProperties.bandwidth;
bandwidthPropertiesDesc->bandwidthUnit = edgeProperties.bandwidthUnit;
bandwidthPropertiesDesc->logicalLatency = edgeProperties.latency;
bandwidthPropertiesDesc->physicalLatency = edgeProperties.latency;
bandwidthPropertiesDesc->latencyUnit = edgeProperties.latencyUnit;
break;
}
}
}
}
}
ze_result_t DeviceImp::getP2PProperties(ze_device_handle_t hPeerDevice,
ze_device_p2p_properties_t *pP2PProperties) {
@ -464,6 +506,8 @@ ze_result_t DeviceImp::getP2PProperties(ze_device_handle_t hPeerDevice,
bandwidthPropertiesDesc->logicalLatency = 0;
bandwidthPropertiesDesc->physicalLatency = 0;
bandwidthPropertiesDesc->latencyUnit = ZE_LATENCY_UNIT_UNKNOWN;
getP2PPropertiesDirectFabricConnection(peerDevice, bandwidthPropertiesDesc);
}
}

View File

@ -148,6 +148,8 @@ struct DeviceImp : public Device {
protected:
void adjustCommandQueueDesc(uint32_t &ordinal, uint32_t &index);
NEO::EngineGroupType getEngineGroupTypeForOrdinal(uint32_t ordinal) const;
void getP2PPropertiesDirectFabricConnection(DeviceImp *peerDeviceImp,
ze_device_p2p_bandwidth_exp_properties_t *bandwidthPropertiesDesc);
NEO::EngineGroupsT subDeviceCopyEngineGroups{};
NEO::GraphicsAllocation *debugSurface = nullptr;

View File

@ -407,6 +407,20 @@ void printP2PProperties(const ze_device_p2p_properties_t &props, bool canAccessP
std::cout << "\t* accessSupported: " << std::boolalpha << static_cast<bool>(!!(props.flags & ZE_DEVICE_P2P_PROPERTY_FLAG_ACCESS)) << "\n";
std::cout << "\t* atomicsSupported: " << std::boolalpha << static_cast<bool>(!!(props.flags & ZE_DEVICE_P2P_PROPERTY_FLAG_ATOMICS)) << "\n";
std::cout << "\t* canAccessPeer: " << std::boolalpha << static_cast<bool>(canAccessPeer) << "\n";
if (props.pNext != nullptr) {
ze_base_desc_t *desc = reinterpret_cast<ze_base_desc_t *>(props.pNext);
if (desc->stype == ZE_STRUCTURE_TYPE_DEVICE_P2P_BANDWIDTH_EXP_PROPERTIES) {
ze_device_p2p_bandwidth_exp_properties_t *expBwProperties =
reinterpret_cast<ze_device_p2p_bandwidth_exp_properties_t *>(desc);
std::cout << " * P2P Exp Properties: Logical BW: " << std::dec << expBwProperties->logicalBandwidth << "\n";
std::cout << " * P2P Exp Properties: Physical BW: " << std::dec << expBwProperties->physicalBandwidth << "\n";
std::cout << " * P2P Exp Properties: BW unit: " << std::dec << expBwProperties->bandwidthUnit << "\n";
std::cout << " * P2P Exp Properties: Logical Latency: " << std::dec << expBwProperties->logicalLatency << "\n";
std::cout << " * P2P Exp Properties: Physical Latency: " << std::dec << expBwProperties->physicalLatency << "\n";
std::cout << " * P2P Exp Properties: Latency unit: " << std::dec << expBwProperties->latencyUnit << "\n";
}
}
}
}

View File

@ -45,7 +45,10 @@ int main(int argc, char *argv[]) {
SUCCESS_OR_TERMINATE(zeDeviceGetProperties(devices[i], &deviceProperties));
printDeviceProperties(deviceProperties);
ze_device_p2p_properties_t deviceP2PProperties;
ze_device_p2p_properties_t deviceP2PProperties{};
ze_device_p2p_bandwidth_exp_properties_t expP2Pproperties{};
expP2Pproperties.stype = ZE_STRUCTURE_TYPE_DEVICE_P2P_BANDWIDTH_EXP_PROPERTIES;
deviceP2PProperties.pNext = &expP2Pproperties;
for (uint32_t j = 0; j < deviceCount; j++) {
if (j == i)
continue;

View File

@ -34,6 +34,7 @@
#include "level_zero/core/source/context/context_imp.h"
#include "level_zero/core/source/driver/driver_handle_imp.h"
#include "level_zero/core/source/driver/host_pointer_manager.h"
#include "level_zero/core/source/fabric/fabric.h"
#include "level_zero/core/source/hw_helpers/l0_hw_helper.h"
#include "level_zero/core/source/image/image.h"
#include "level_zero/core/test/unit_tests/fixtures/device_fixture.h"
@ -4042,5 +4043,149 @@ TEST_F(DeviceSimpleTests, givenValidDeviceThenValidCoreDeviceIsRetrievedWithGetS
EXPECT_EQ(device, specializedDevice);
}
using P2pBandwidthPropertiesTest = MultipleDevicesTest;
TEST_F(P2pBandwidthPropertiesTest, GivenDirectFabricConnectionBetweenDevicesWhenQueryingBandwidthPropertiesThenCorrectPropertiesAreSet) {
const uint32_t testLatency = 1;
const uint32_t testBandwidth = 20;
driverHandle->initializeVertexes();
L0::Device *device0 = driverHandle->devices[0];
L0::Device *device1 = driverHandle->devices[1];
FabricEdge testEdge{};
testEdge.vertexA = static_cast<DeviceImp *>(device0)->fabricVertex;
testEdge.vertexB = static_cast<DeviceImp *>(device1)->fabricVertex;
const char *linkModel = "XeLink";
memcpy_s(testEdge.properties.model, ZE_MAX_FABRIC_EDGE_MODEL_EXP_SIZE, linkModel, strlen(linkModel));
testEdge.properties.bandwidth = testBandwidth;
testEdge.properties.latency = testLatency;
testEdge.properties.bandwidthUnit = ZE_BANDWIDTH_UNIT_BYTES_PER_NANOSEC;
testEdge.properties.latencyUnit = ZE_LATENCY_UNIT_HOP;
driverHandle->fabricEdges.push_back(&testEdge);
ze_device_p2p_properties_t p2pProperties = {};
ze_device_p2p_bandwidth_exp_properties_t p2pBandwidthProps = {};
p2pProperties.pNext = &p2pBandwidthProps;
p2pBandwidthProps.stype = ZE_STRUCTURE_TYPE_DEVICE_P2P_BANDWIDTH_EXP_PROPERTIES;
p2pBandwidthProps.pNext = nullptr;
device0->getP2PProperties(device1, &p2pProperties);
EXPECT_EQ(testBandwidth, p2pBandwidthProps.logicalBandwidth);
EXPECT_EQ(testBandwidth, p2pBandwidthProps.physicalBandwidth);
EXPECT_EQ(ZE_BANDWIDTH_UNIT_BYTES_PER_NANOSEC, p2pBandwidthProps.bandwidthUnit);
EXPECT_EQ(testLatency, p2pBandwidthProps.logicalLatency);
EXPECT_EQ(testLatency, p2pBandwidthProps.physicalLatency);
EXPECT_EQ(ZE_LATENCY_UNIT_HOP, p2pBandwidthProps.latencyUnit);
driverHandle->fabricEdges.pop_back();
}
TEST_F(P2pBandwidthPropertiesTest, GivenNoXeLinkFabricConnectionBetweenDevicesWhenQueryingBandwidthPropertiesThenBandwidthIsZero) {
const uint32_t testLatency = 1;
const uint32_t testBandwidth = 20;
driverHandle->initializeVertexes();
L0::Device *device0 = driverHandle->devices[0];
L0::Device *device1 = driverHandle->devices[1];
FabricEdge testEdge{};
testEdge.vertexA = static_cast<DeviceImp *>(device0)->fabricVertex;
testEdge.vertexB = static_cast<DeviceImp *>(device1)->fabricVertex;
const char *linkModel = "Dummy";
memcpy_s(testEdge.properties.model, ZE_MAX_FABRIC_EDGE_MODEL_EXP_SIZE, linkModel, strlen(linkModel));
testEdge.properties.bandwidth = testBandwidth;
testEdge.properties.latency = testLatency;
testEdge.properties.bandwidthUnit = ZE_BANDWIDTH_UNIT_BYTES_PER_NANOSEC;
testEdge.properties.latencyUnit = ZE_LATENCY_UNIT_HOP;
driverHandle->fabricEdges.push_back(&testEdge);
ze_device_p2p_properties_t p2pProperties = {};
ze_device_p2p_bandwidth_exp_properties_t p2pBandwidthProps = {};
p2pProperties.pNext = &p2pBandwidthProps;
p2pBandwidthProps.stype = ZE_STRUCTURE_TYPE_DEVICE_P2P_BANDWIDTH_EXP_PROPERTIES;
p2pBandwidthProps.pNext = nullptr;
// Calling with "Dummy" link
device0->getP2PProperties(device1, &p2pProperties);
EXPECT_EQ(0u, p2pBandwidthProps.logicalBandwidth);
driverHandle->fabricEdges.pop_back();
}
TEST_F(P2pBandwidthPropertiesTest, GivenNoDirectFabricConnectionBetweenDevicesWhenQueryingBandwidthPropertiesThenBandwidthIsZero) {
driverHandle->initializeVertexes();
L0::Device *device0 = driverHandle->devices[0];
L0::Device *device1 = driverHandle->devices[1];
ze_device_p2p_properties_t p2pProperties = {};
ze_device_p2p_bandwidth_exp_properties_t p2pBandwidthProps = {};
p2pProperties.pNext = &p2pBandwidthProps;
p2pBandwidthProps.stype = ZE_STRUCTURE_TYPE_DEVICE_P2P_BANDWIDTH_EXP_PROPERTIES;
p2pBandwidthProps.pNext = nullptr;
// By default Xelink connections are not available.
// So getting the p2p properties without it.
device0->getP2PProperties(device1, &p2pProperties);
EXPECT_EQ(0u, p2pBandwidthProps.logicalBandwidth);
}
TEST_F(P2pBandwidthPropertiesTest, GivenFabricVerticesAreNotInitializedWhenQueryingBandwidthPropertiesThenFabricVerticesAreInitialized) {
L0::Device *device0 = driverHandle->devices[0];
L0::Device *device1 = driverHandle->devices[1];
ze_device_p2p_properties_t p2pProperties = {};
ze_device_p2p_bandwidth_exp_properties_t p2pBandwidthProps = {};
p2pProperties.pNext = &p2pBandwidthProps;
p2pBandwidthProps.stype = ZE_STRUCTURE_TYPE_DEVICE_P2P_BANDWIDTH_EXP_PROPERTIES;
p2pBandwidthProps.pNext = nullptr;
// Calling without initialization
device0->getP2PProperties(device1, &p2pProperties);
EXPECT_NE(driverHandle->fabricVertices.size(), 0u);
}
TEST_F(P2pBandwidthPropertiesTest, GivenFabricVerticesAreNotAvailableForDevicesWhenQueryingBandwidthPropertiesThenBandwidthIsZero) {
L0::Device *device0 = driverHandle->devices[0];
L0::Device *device1 = driverHandle->devices[1];
driverHandle->initializeVertexes();
// Check for device 0
auto backupFabricVertex = static_cast<DeviceImp *>(device0)->fabricVertex;
static_cast<DeviceImp *>(device0)->fabricVertex = nullptr;
ze_device_p2p_properties_t p2pProperties = {};
ze_device_p2p_bandwidth_exp_properties_t p2pBandwidthProps = {};
p2pProperties.pNext = &p2pBandwidthProps;
p2pBandwidthProps.stype = ZE_STRUCTURE_TYPE_DEVICE_P2P_BANDWIDTH_EXP_PROPERTIES;
p2pBandwidthProps.pNext = nullptr;
device0->getP2PProperties(device1, &p2pProperties);
EXPECT_EQ(p2pBandwidthProps.logicalBandwidth, 0u);
static_cast<DeviceImp *>(device0)->fabricVertex = backupFabricVertex;
// Check for device 1
backupFabricVertex = static_cast<DeviceImp *>(device1)->fabricVertex;
static_cast<DeviceImp *>(device1)->fabricVertex = nullptr;
device0->getP2PProperties(device1, &p2pProperties);
EXPECT_EQ(p2pBandwidthProps.logicalBandwidth, 0u);
static_cast<DeviceImp *>(device1)->fabricVertex = backupFabricVertex;
}
} // namespace ult
} // namespace L0