1 /*
2 * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23
24 #include "KFDTopologyTest.hpp"
25 #include <vector>
26 #include <string>
27
28 // @todo complete topology test according to whats in: hsathk\source\windows\kmt_topology.cpp
29
30 const unsigned long long KFDTopologyTest::c_4Gigabyte = (1ull << 32) - 1;
31 const unsigned long long KFDTopologyTest::c_40BitAddressSpace = (1ull << 40);
32
TEST_F(KFDTopologyTest,BasicTest)33 TEST_F(KFDTopologyTest , BasicTest) {
34 TEST_START(TESTPROFILE_RUNALL)
35
36 const HsaNodeProperties *pNodeProperties;
37
38 // goes over all nodes in the sytem properties and check the basic info received
39 for (unsigned node = 0; node < m_SystemProperties.NumNodes; node++) {
40 pNodeProperties = m_NodeInfo.GetNodeProperties(node);
41 if (pNodeProperties != NULL) {
42 // checking for cpu core only if it's a cpu only node or if its KAVERY apu.
43 if (pNodeProperties->DeviceId == 0 || FamilyIdFromNode(pNodeProperties) == FAMILY_KV) {
44 EXPECT_GT(pNodeProperties->NumCPUCores, HSAuint32(0)) << "Node index: " << node << " No CPUs core are connected for node index";
45 }
46
47 // if it's not a cpu only node, look for a gpu core
48 if (pNodeProperties->DeviceId != 0) {
49 EXPECT_GT(pNodeProperties->NumFComputeCores, HSAuint32(0)) << "Node index: " << node << "No GPUs core are connected.";
50 // EngineId only applies to GPU, not CPU-only nodes
51 EXPECT_GT(pNodeProperties->EngineId.ui32.uCode, 0) << "uCode version is 0";
52 EXPECT_GE(pNodeProperties->EngineId.ui32.Major, 7) << "Major Version is less than 7";
53 EXPECT_LT(pNodeProperties->EngineId.ui32.Minor, 10) << "Minor Version is greater than 9";
54 EXPECT_LT(pNodeProperties->EngineId.ui32.Stepping, 10) << "Stepping is greater than 9";
55 EXPECT_GT(pNodeProperties->uCodeEngineVersions.uCodeSDMA, 0) << "sDMA firmware version is 0";
56 }
57 EXPECT_GT(pNodeProperties->NumMemoryBanks, HSAuint32(0)) << "Node index: " << node << "No MemoryBanks.";
58 EXPECT_GT(pNodeProperties->NumCaches, HSAuint32(0)) << "Node index: " << node << "No Caches.";
59 }
60 }
61
62 TEST_END
63 }
64
65 // this test verify failure status on hsaKmtGetNodeProperties with invalid params
TEST_F(KFDTopologyTest,GetNodePropertiesInvalidParams)66 TEST_F(KFDTopologyTest, GetNodePropertiesInvalidParams) {
67 TEST_START(TESTPROFILE_RUNALL)
68
69 EXPECT_EQ(HSAKMT_STATUS_INVALID_PARAMETER, hsaKmtGetNodeProperties(0, NULL));
70
71 TEST_END
72 }
73
74 // this test verify failure status on hsaKmtGetNodeProperties with invalid params
TEST_F(KFDTopologyTest,GetNodePropertiesInvalidNodeNum)75 TEST_F(KFDTopologyTest, GetNodePropertiesInvalidNodeNum) {
76 TEST_START(TESTPROFILE_RUNALL)
77
78 HsaNodeProperties nodeProperties;
79 memset(&nodeProperties, 0, sizeof(nodeProperties));
80 EXPECT_EQ(HSAKMT_STATUS_INVALID_PARAMETER, hsaKmtGetNodeProperties(m_SystemProperties.NumNodes, &nodeProperties));
81
82 TEST_END
83 }
84
85 // test that we can get memory property successfully per node
86 // @todo check validity of values returned
TEST_F(KFDTopologyTest,GetNodeMemoryProperties)87 TEST_F(KFDTopologyTest, GetNodeMemoryProperties) {
88 TEST_START(TESTPROFILE_RUNALL)
89 const HsaNodeProperties *pNodeProperties;
90
91 for (unsigned node = 0; node < m_SystemProperties.NumNodes; node++) {
92 pNodeProperties = m_NodeInfo.GetNodeProperties(node);
93
94 if (pNodeProperties != NULL) {
95 HsaMemoryProperties *memoryProperties = new HsaMemoryProperties[pNodeProperties->NumMemoryBanks];
96 EXPECT_SUCCESS(hsaKmtGetNodeMemoryProperties(node, pNodeProperties->NumMemoryBanks, memoryProperties));
97 delete [] memoryProperties;
98 }
99 }
100
101 TEST_END
102 }
103
104
105 // test the GPU local memory aperture is valid.
TEST_F(KFDTopologyTest,GpuvmApertureValidate)106 TEST_F(KFDTopologyTest, GpuvmApertureValidate) {
107 TEST_REQUIRE_NO_ENV_CAPABILITIES(ENVCAPS_32BITLINUX);
108
109 TEST_START(TESTPROFILE_RUNALL)
110 const HsaNodeProperties *pNodeProperties;
111 const std::vector<int> GpuNodes = m_NodeInfo.GetNodesWithGPU();
112
113 for (unsigned i = 0; i < GpuNodes.size(); i++) {
114 pNodeProperties = m_NodeInfo.GetNodeProperties(GpuNodes.at(i));
115 if (pNodeProperties != NULL) {
116 if (!is_dgpu() && !(FamilyIdFromNode(pNodeProperties) == FAMILY_KV)) {
117 LOG() << "Skipping test: GPUVM framebuffer heap not exposed on APU except Kaveri" << std::endl;
118 return;
119 }
120 HsaMemoryProperties *memoryProperties = new HsaMemoryProperties[pNodeProperties->NumMemoryBanks];
121 EXPECT_SUCCESS(hsaKmtGetNodeMemoryProperties(GpuNodes.at(i), pNodeProperties->NumMemoryBanks, memoryProperties));
122 bool GpuVMHeapFound = false;
123 for (unsigned int bank = 0 ; bank < pNodeProperties->NumMemoryBanks ; bank++) {
124 // Check for either private (small-bar/APU) or public (large-bar)
125 if ((HSA_HEAPTYPE_FRAME_BUFFER_PRIVATE == memoryProperties[bank].HeapType) ||
126 (HSA_HEAPTYPE_FRAME_BUFFER_PUBLIC == memoryProperties[bank].HeapType))
127 GpuVMHeapFound = true;
128 }
129 EXPECT_TRUE(GpuVMHeapFound);
130 delete [] memoryProperties;
131 }
132 }
133
134 TEST_END
135 }
136
137 // test that we can get cache property successfully per node
138 // @todo check validity of values returned
TEST_F(KFDTopologyTest,GetNodeCacheProperties)139 TEST_F(KFDTopologyTest, GetNodeCacheProperties) {
140 TEST_START(TESTPROFILE_RUNALL)
141
142 const HsaNodeProperties *pNodeProperties;
143
144 for (unsigned node = 0; node < m_SystemProperties.NumNodes; node++) {
145 pNodeProperties = m_NodeInfo.GetNodeProperties(node);
146 if (pNodeProperties != NULL) {
147 HsaCacheProperties *cacheProperties = new HsaCacheProperties[pNodeProperties->NumCaches];
148 EXPECT_SUCCESS(hsaKmtGetNodeCacheProperties(node, pNodeProperties->CComputeIdLo, pNodeProperties->NumCaches, cacheProperties));
149 if (pNodeProperties->NumCPUCores > 0) { // this is a CPU node
150 LOG() << "CPU Node " << std::dec << node << ": " << pNodeProperties->NumCaches << " caches" << std::endl;
151 for (unsigned n = 0; n < pNodeProperties->NumCaches; n++) {
152 LOG()<< n << " - Level " << cacheProperties[n].CacheLevel <<
153 " Type " << cacheProperties[n].CacheType.Value <<
154 " Size " << (cacheProperties[n].CacheSize >> 10) << "K " <<
155 " Associativity " << cacheProperties[n].CacheAssociativity <<
156 " LineSize " << cacheProperties[n].CacheLineSize <<
157 " LinesPerTag " << cacheProperties[n].CacheLinesPerTag << std::endl;
158 char string[1024] = "";
159 char sibling[5] = "";
160 for (unsigned i = 0; i < 256; i++) {
161 if (cacheProperties[n].SiblingMap[i]) {
162 sprintf(sibling, "%d,", i);
163 strcat(string, sibling);
164 }
165 }
166 LOG() << " ProcIdLow " << cacheProperties[n].ProcessorIdLow <<
167 " SiblingMap " << string << std::endl;
168 }
169 }
170 delete [] cacheProperties;
171 }
172 }
173
174 TEST_END
175 }
176
177 // test that we can get NodeIoLink property successfully per node
178 // @todo check validity of values returned
179 // GetNodeIoLinkProperties is disabled for now, test fails due to bug in BIOS
TEST_F(KFDTopologyTest,GetNodeIoLinkProperties)180 TEST_F(KFDTopologyTest, GetNodeIoLinkProperties) {
181 TEST_START(TESTPROFILE_RUNALL)
182 const HsaNodeProperties *pNodeProperties;
183 int linkId;
184 char c;
185
186 LOG() << "Topology. [FromNode]--(Weight)-->[ToNode]" << std::endl;
187
188 for (unsigned node = 0; node < m_SystemProperties.NumNodes; node++) {
189 pNodeProperties = m_NodeInfo.GetNodeProperties(node);
190
191 if (pNodeProperties != NULL) {
192 HsaIoLinkProperties *IolinkProperties = new HsaIoLinkProperties[pNodeProperties->NumIOLinks];
193 EXPECT_SUCCESS(hsaKmtGetNodeIoLinkProperties(node, pNodeProperties->NumIOLinks, IolinkProperties));
194 if (pNodeProperties->NumIOLinks == 0) {
195 // No io_links. Just Print the node
196 LOG() << "[" << node << "]" << std::endl;
197 continue;
198 }
199
200 for (linkId = 0; linkId < pNodeProperties->NumIOLinks; linkId++) {
201 if (linkId == 0) {
202 // First io_link. Print Parent Node and io_link Node
203 LOG() << "[" << node << "]--(" << IolinkProperties[linkId].Weight << ")-->" <<
204 "[" << IolinkProperties[linkId].NodeTo << "]" << std::endl;
205 continue;
206 }
207 if (linkId == (pNodeProperties->NumIOLinks - 1))
208 c = '`'; // last node
209 else
210 c = '|';
211 LOG() << " " << c << "--(" << IolinkProperties[linkId].Weight << ")-->" <<
212 "[" << IolinkProperties[linkId].NodeTo << "]" << std::endl;
213 }
214 LOG() << std::endl;
215 delete [] IolinkProperties;
216 }
217 }
218
219 TEST_END
220 }
221