|
47 | 47 |
|
48 | 48 | #include <hip/hip_runtime_api.h> |
49 | 49 |
|
| 50 | +#include <algorithm> |
50 | 51 | #include <cstdlib> |
51 | | -#include <iostream> |
52 | 52 | #include <fstream> |
| 53 | +#include <iostream> |
53 | 54 | #include <map> |
54 | 55 | #include <vector> |
55 | | -#include <algorithm> |
56 | 56 |
|
57 | | -#define HIP_CHECK(expression) \ |
58 | | -{ \ |
59 | | - const hipError_t status = expression; \ |
60 | | - if (status != hipSuccess) \ |
61 | | - { \ |
62 | | - std::cerr << "HIP error " << status \ |
63 | | - << ": " << hipGetErrorString(status) \ |
64 | | - << " at " << __FILE__ << ":" \ |
65 | | - << __LINE__ << std::endl; \ |
66 | | - std::exit(EXIT_FAILURE); \ |
67 | | - } \ |
68 | | -} |
| 57 | +#define HIP_CHECK(expression) \ |
| 58 | + { \ |
| 59 | + const hipError_t status = expression; \ |
| 60 | + if(status != hipSuccess) \ |
| 61 | + { \ |
| 62 | + std::cerr << "HIP error " << status << ": " << hipGetErrorString(status) << " at " \ |
| 63 | + << __FILE__ << ":" << __LINE__ << std::endl; \ |
| 64 | + std::exit(EXIT_FAILURE); \ |
| 65 | + } \ |
| 66 | + } |
69 | 67 |
|
70 | 68 | int main(int argc, char* argv[]) |
71 | 69 | { |
72 | | - if (argc != 2) |
73 | | - { |
74 | | - std::cout << "Usage: ./enum_devices <output file path>" << std::endl; |
75 | | - std::exit(EXIT_FAILURE); |
76 | | - } |
| 70 | + if(argc != 2) |
| 71 | + { |
| 72 | + std::cout << "Usage: ./enum_devices <output file path>" << std::endl; |
| 73 | + std::exit(EXIT_FAILURE); |
| 74 | + } |
77 | 75 |
|
78 | | - std::ofstream out_file; |
79 | | - out_file.open(argv[1]); |
| 76 | + std::ofstream out_file; |
| 77 | + out_file.open(argv[1]); |
80 | 78 |
|
81 | | - // Figure out how many devices are in the system. |
| 79 | + // Figure out how many devices are in the system. |
82 | 80 | int dev_count; |
83 | 81 | HIP_CHECK(hipGetDeviceCount(&dev_count)); |
84 | 82 |
|
85 | | - // There could be more than one device of each type. |
86 | | - // Build a mapping of gfxID (string) to a vector of device IDs (unsigned ints). |
87 | | - std::map<std::string, std::vector<unsigned int>> names_to_ids; |
88 | | - // This entry will hold all device IDs. |
89 | | - names_to_ids["gpus"] = {}; |
| 83 | + // There could be more than one device of each type. |
| 84 | + // Build a mapping of gfxID (string) to a vector of device IDs (unsigned ints). |
| 85 | + std::map<std::string, std::vector<unsigned int>> names_to_ids; |
| 86 | + // This entry will hold all device IDs. |
| 87 | + names_to_ids["gpus"] = {}; |
90 | 88 |
|
91 | | - // Populate the map |
92 | | - for (unsigned int dev_id = 0; dev_id < dev_count; ++dev_id) |
| 89 | + // Populate the map |
| 90 | + for(unsigned int dev_id = 0; dev_id < static_cast<unsigned int>(dev_count); ++dev_id) |
93 | 91 | { |
94 | 92 | hipDeviceProp_t dev_prop; |
95 | 93 | HIP_CHECK(hipGetDeviceProperties(&dev_prop, dev_id)); |
96 | | - std::string name(dev_prop.gcnArchName); |
97 | | - |
98 | | - if (names_to_ids.find(name) == names_to_ids.end()) |
99 | | - names_to_ids[name] = std::vector<unsigned int>({dev_id}); |
100 | | - else |
101 | | - names_to_ids[name].push_back(dev_id); |
102 | | - |
103 | | - // Add every device ID to the "gpus" entry |
104 | | - names_to_ids["gpus"].push_back(dev_id); |
| 94 | + std::string name(dev_prop.gcnArchName); |
| 95 | + |
| 96 | + if(names_to_ids.find(name) == names_to_ids.end()) |
| 97 | + names_to_ids[name] = std::vector<unsigned int>({dev_id}); |
| 98 | + else |
| 99 | + names_to_ids[name].push_back(dev_id); |
| 100 | + |
| 101 | + // Add every device ID to the "gpus" entry |
| 102 | + names_to_ids["gpus"].push_back(dev_id); |
105 | 103 | } |
106 | 104 |
|
107 | | - // Begin the JSON output. The first few lines are boilerplate: |
108 | | - out_file << "{" << std::endl << |
109 | | - " \"version\": {" << std::endl << |
110 | | - " \"major\": 1," << std::endl << |
111 | | - " \"minor\": 0" << std::endl << |
112 | | - " }," << std::endl << |
113 | | - " \"local\": [" << std::endl << |
114 | | - " {" << std::endl; |
115 | | - |
116 | | - // Add one object for each gfxID. |
117 | | - // Each gfxID-keyed object will contain an array of device IDs. |
118 | | - int key_index = 0; |
119 | | - for (auto& name_it : names_to_ids) |
120 | | - { |
121 | | - out_file << " \"" << name_it.first << "\": [" << std::endl; |
122 | | - |
123 | | - // The gfxIDs (names) are already sorted by the map, but the |
124 | | - // device IDs may not be in order. |
125 | | - // Sorting them is not technically necessary, but it's nice |
126 | | - // to have a consistent output on each run so that the resource |
127 | | - // spec file stays the same. |
128 | | - std::sort(name_it.second.begin(), name_it.second.end()); |
129 | | - int id_index = 0; |
130 | | - for (const auto& id_it : name_it.second) |
131 | | - { |
132 | | - out_file << " {" << std::endl; |
133 | | - // Note: ctest expects ids to be specified as a string (quoted), not an integer. |
134 | | - out_file << " \"id\": \"" << id_it << "\"" << std::endl; |
135 | | - out_file << " }"; |
136 | | - |
137 | | - if (id_index < name_it.second.size() - 1) |
138 | | - out_file << ","; |
139 | | - out_file << std::endl; |
140 | | - id_index++; |
141 | | - } |
142 | | - |
143 | | - out_file << " ]"; |
144 | | - |
145 | | - if (key_index < names_to_ids.size() - 1) |
146 | | - out_file << ","; |
147 | | - out_file << std::endl; |
148 | | - key_index++; |
149 | | - } |
150 | | - |
151 | | - // Close out the remaining open objects and arrays. |
152 | | - out_file << " }" << std::endl << |
153 | | - " ]" << std::endl << |
154 | | - "}" << std::endl; |
155 | | - |
156 | | - out_file.close(); |
157 | | - |
| 105 | + // Begin the JSON output. The first few lines are boilerplate: |
| 106 | + out_file << "{" << std::endl |
| 107 | + << " \"version\": {" << std::endl |
| 108 | + << " \"major\": 1," << std::endl |
| 109 | + << " \"minor\": 0" << std::endl |
| 110 | + << " }," << std::endl |
| 111 | + << " \"local\": [" << std::endl |
| 112 | + << " {" << std::endl; |
| 113 | + |
| 114 | + // Add one object for each gfxID. |
| 115 | + // Each gfxID-keyed object will contain an array of device IDs. |
| 116 | + unsigned int key_index = 0; |
| 117 | + for(auto& name_it : names_to_ids) |
| 118 | + { |
| 119 | + out_file << " \"" << name_it.first << "\": [" << std::endl; |
| 120 | + |
| 121 | + // The gfxIDs (names) are already sorted by the map, but the |
| 122 | + // device IDs may not be in order. |
| 123 | + // Sorting them is not technically necessary, but it's nice |
| 124 | + // to have a consistent output on each run so that the resource |
| 125 | + // spec file stays the same. |
| 126 | + std::sort(name_it.second.begin(), name_it.second.end()); |
| 127 | + unsigned int id_index = 0; |
| 128 | + for(const auto& id_it : name_it.second) |
| 129 | + { |
| 130 | + out_file << " {" << std::endl; |
| 131 | + // Note: ctest expects ids to be specified as a string (quoted), not an integer. |
| 132 | + out_file << " \"id\": \"" << id_it << "\"" << std::endl; |
| 133 | + out_file << " }"; |
| 134 | + |
| 135 | + if(id_index < name_it.second.size() - 1) |
| 136 | + out_file << ","; |
| 137 | + out_file << std::endl; |
| 138 | + id_index++; |
| 139 | + } |
| 140 | + |
| 141 | + out_file << " ]"; |
| 142 | + |
| 143 | + if(key_index < names_to_ids.size() - 1) |
| 144 | + out_file << ","; |
| 145 | + out_file << std::endl; |
| 146 | + key_index++; |
| 147 | + } |
| 148 | + |
| 149 | + // Close out the remaining open objects and arrays. |
| 150 | + out_file << " }" << std::endl << " ]" << std::endl << "}" << std::endl; |
| 151 | + |
| 152 | + out_file.close(); |
| 153 | + |
158 | 154 | return EXIT_SUCCESS; |
159 | 155 | } |
0 commit comments