• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (c) 2017-2020 Advanced Micro Devices, Inc. All rights reserved.
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a copy
5 // of this software and associated documentation files (the "Software"), to deal
6 // in the Software without restriction, including without limitation the rights
7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 // copies of the Software, and to permit persons to whom the Software is
9 // 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 THE
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 // THE SOFTWARE.
21 //
22 
23 #pragma once
24 
25 #include "VmaUsage.h"
26 
27 #include <iostream>
28 #include <fstream>
29 #include <vector>
30 #include <memory>
31 #include <algorithm>
32 #include <numeric>
33 #include <array>
34 #include <type_traits>
35 #include <utility>
36 #include <chrono>
37 #include <string>
38 #include <limits>
39 
40 #include <cassert>
41 #include <cstdlib>
42 #include <cstdio>
43 #include <cstdarg>
44 
45 typedef std::chrono::high_resolution_clock::time_point time_point;
46 typedef std::chrono::high_resolution_clock::duration duration;
47 
ToFloatSeconds(duration d)48 inline float ToFloatSeconds(duration d)
49 {
50     return std::chrono::duration_cast<std::chrono::duration<float>>(d).count();
51 }
52 
53 void SecondsToFriendlyStr(float seconds, std::string& out);
54 
55 template <typename T>
ceil_div(T x,T y)56 T ceil_div(T x, T y)
57 {
58     return (x+y-1) / y;
59 }
60 template <typename T>
round_div(T x,T y)61 inline T round_div(T x, T y)
62 {
63     return (x+y/(T)2) / y;
64 }
65 
66 template <typename T>
align_up(T val,T align)67 inline T align_up(T val, T align)
68 {
69     return (val + align - 1) / align * align;
70 }
71 
72 struct StrRange
73 {
74     const char* beg;
75     const char* end;
76 
StrRangeStrRange77     StrRange() { }
StrRangeStrRange78     StrRange(const char* beg, const char* end) : beg(beg), end(end) { }
StrRangeStrRange79     explicit StrRange(const char* sz) : beg(sz), end(sz + strlen(sz)) { }
StrRangeStrRange80     explicit StrRange(const std::string& s) : beg(s.data()), end(s.data() + s.length()) { }
81 
lengthStrRange82     size_t length() const { return end - beg; }
to_strStrRange83     void to_str(std::string& out) const { out.assign(beg, end); }
84 };
85 
StrRangeEq(const StrRange & lhs,const char * rhsSz)86 inline bool StrRangeEq(const StrRange& lhs, const char* rhsSz)
87 {
88     const size_t rhsLen = strlen(rhsSz);
89     return rhsLen == lhs.length() &&
90         memcmp(lhs.beg, rhsSz, rhsLen) == 0;
91 }
92 
StrRangeToUint(const StrRange & s,uint32_t & out)93 inline bool StrRangeToUint(const StrRange& s, uint32_t& out)
94 {
95     char* end = (char*)s.end;
96     out = (uint32_t)strtoul(s.beg, &end, 10);
97     return end == s.end;
98 }
StrRangeToUint(const StrRange & s,uint64_t & out)99 inline bool StrRangeToUint(const StrRange& s, uint64_t& out)
100 {
101     char* end = (char*)s.end;
102     out = (uint64_t)strtoull(s.beg, &end, 10);
103     return end == s.end;
104 }
StrRangeToPtr(const StrRange & s,uint64_t & out)105 inline bool StrRangeToPtr(const StrRange& s, uint64_t& out)
106 {
107     char* end = (char*)s.end;
108     out = (uint64_t)strtoull(s.beg, &end, 16);
109     return end == s.end;
110 }
StrRangeToFloat(const StrRange & s,float & out)111 inline bool StrRangeToFloat(const StrRange& s, float& out)
112 {
113     char* end = (char*)s.end;
114     out = strtof(s.beg, &end);
115     return end == s.end;
116 }
StrRangeToBool(const StrRange & s,bool & out)117 inline bool StrRangeToBool(const StrRange& s, bool& out)
118 {
119     if(s.end - s.beg == 1)
120     {
121         if(*s.beg == '1')
122         {
123             out = true;
124         }
125         else if(*s.beg == '0')
126         {
127             out = false;
128         }
129         else
130         {
131             return false;
132         }
133     }
134     else
135     {
136         return false;
137     }
138 
139     return true;
140 }
141 bool StrRangeToPtrList(const StrRange& s, std::vector<uint64_t>& out);
142 
143 class LineSplit
144 {
145 public:
LineSplit(const char * data,size_t numBytes)146     LineSplit(const char* data, size_t numBytes) :
147         m_Data(data),
148         m_NumBytes(numBytes),
149         m_NextLineBeg(0),
150         m_NextLineIndex(0)
151     {
152     }
153 
154     bool GetNextLine(StrRange& out);
GetNextLineIndex()155     size_t GetNextLineIndex() const { return m_NextLineIndex; }
156 
157 private:
158     const char* const m_Data;
159     const size_t m_NumBytes;
160     size_t m_NextLineBeg;
161     size_t m_NextLineIndex;
162 };
163 
164 class CsvSplit
165 {
166 public:
167     static const size_t RANGE_COUNT_MAX = 32;
168 
169     void Set(const StrRange& line, size_t maxCount = RANGE_COUNT_MAX);
170 
GetLine()171     const StrRange& GetLine() const { return m_Line; }
172 
GetCount()173     size_t GetCount() const { return m_Count; }
GetRange(size_t index)174     StrRange GetRange(size_t index) const
175     {
176         if(index < m_Count)
177         {
178             return StrRange {
179                 m_Line.beg + m_Ranges[index * 2],
180                 m_Line.beg + m_Ranges[index * 2 + 1] };
181         }
182         else
183         {
184             return StrRange{0, 0};
185         }
186     }
187 
188 private:
189     StrRange m_Line = { nullptr, nullptr };
190     size_t m_Count = 0;
191     size_t m_Ranges[RANGE_COUNT_MAX * 2]; // Pairs of begin-end.
192 };
193 
194 class CmdLineParser
195 {
196 public:
197 	enum RESULT
198 	{
199 		RESULT_OPT,
200 		RESULT_PARAMETER,
201 		RESULT_END,
202 		RESULT_ERROR,
203 	};
204 
205 	CmdLineParser(int argc, char **argv);
206 	CmdLineParser(const char *CmdLine);
207 
208     void RegisterOpt(uint32_t Id, char Opt, bool Parameter);
209 	void RegisterOpt(uint32_t Id, const std::string &Opt, bool Parameter);
210 
211     RESULT ReadNext();
212 	uint32_t GetOptId();
213 	const std::string & GetParameter();
214 
215 private:
216 	struct SHORT_OPT
217 	{
218 		uint32_t Id;
219 		char Opt;
220 		bool Parameter;
221 
SHORT_OPTSHORT_OPT222 		SHORT_OPT(uint32_t Id, char Opt, bool Parameter) : Id(Id), Opt(Opt), Parameter(Parameter) { }
223 	};
224 
225 	struct LONG_OPT
226 	{
227 		uint32_t Id;
228 		std::string Opt;
229 		bool Parameter;
230 
LONG_OPTLONG_OPT231 		LONG_OPT(uint32_t Id, std::string Opt, bool Parameter) : Id(Id), Opt(Opt), Parameter(Parameter) { }
232 	};
233 
234 	char **m_argv;
235 	const char *m_CmdLine;
236 	int m_argc;
237 	size_t m_CmdLineLength;
238 	size_t m_ArgIndex;
239 
240 	bool ReadNextArg(std::string *OutArg);
241 
242 	std::vector<SHORT_OPT> m_ShortOpts;
243 	std::vector<LONG_OPT> m_LongOpts;
244 
245 	SHORT_OPT * FindShortOpt(char Opt);
246 	LONG_OPT * FindLongOpt(const std::string &Opt);
247 
248 	bool m_InsideMultioption;
249 	std::string m_LastArg;
250 	size_t m_LastArgIndex;
251 	uint32_t m_LastOptId;
252 	std::string m_LastParameter;
253 };
254 
255 /*
256 Parses and stores a sequence of ranges.
257 
258 Upper range is inclusive.
259 
260 Examples:
261 
262     "1" -> [ {1, 1} ]
263     "1,10" -> [ {1, 1}, {10, 10} ]
264     "2-6" -> [ {2, 6} ]
265     "-8" -> [ {MIN, 8} ]
266     "12-" -> [ {12, MAX} ]
267     "1-10,12,15-" -> [ {1, 10}, {12, 12}, {15, MAX} ]
268 
269 TODO: Optimize it: Do sorting and merging while parsing. Do binary search while
270 reading.
271 */
272 template<typename T>
273 class RangeSequence
274 {
275 public:
276     typedef std::pair<T, T> RangeType;
277 
Clear()278     void Clear() { m_Ranges.clear(); }
279     bool Parse(const StrRange& str);
280 
IsEmpty()281     bool IsEmpty() const { return m_Ranges.empty(); }
GetCount()282     size_t GetCount() const { return m_Ranges.size(); }
GetRanges()283     const RangeType* GetRanges() const { return m_Ranges.data(); }
284 
285     bool Includes(T number) const;
286 
287 private:
288     std::vector<RangeType> m_Ranges;
289 };
290 
291 template<typename T>
Parse(const StrRange & str)292 bool RangeSequence<T>::Parse(const StrRange& str)
293 {
294     m_Ranges.clear();
295 
296     StrRange currRange = { str.beg, str.beg };
297     while(currRange.beg < str.end)
298     {
299         currRange.end = currRange.beg + 1;
300         // Find next ',' or the end.
301         while(currRange.end < str.end && *currRange.end != ',')
302         {
303             ++currRange.end;
304         }
305 
306         // Find '-' within this range.
307         const char* hyphenPos = currRange.beg;
308         while(hyphenPos < currRange.end && *hyphenPos != '-')
309         {
310             ++hyphenPos;
311         }
312 
313         // No hyphen - single number like '10'.
314         if(hyphenPos == currRange.end)
315         {
316             RangeType range;
317             if(!StrRangeToUint(currRange, range.first))
318             {
319                 return false;
320             }
321             range.second = range.first;
322             m_Ranges.push_back(range);
323         }
324         // Hyphen at the end, like '10-'.
325         else if(hyphenPos + 1 == currRange.end)
326         {
327             const StrRange numberRange = { currRange.beg, hyphenPos };
328             RangeType range;
329             if(!StrRangeToUint(numberRange, range.first))
330             {
331                 return false;
332             }
333             range.second = std::numeric_limits<T>::max();
334             m_Ranges.push_back(range);
335         }
336         // Hyphen at the beginning, like "-10".
337         else if(hyphenPos == currRange.beg)
338         {
339             const StrRange numberRange = { currRange.beg + 1, currRange.end };
340             RangeType range;
341             range.first = std::numeric_limits<T>::min();
342             if(!StrRangeToUint(numberRange, range.second))
343             {
344                 return false;
345             }
346             m_Ranges.push_back(range);
347         }
348         // Hyphen in the middle, like "1-10".
349         else
350         {
351             const StrRange numberRange1 = { currRange.beg, hyphenPos };
352             const StrRange numberRange2 = { hyphenPos + 1, currRange.end };
353             RangeType range;
354             if(!StrRangeToUint(numberRange1, range.first) ||
355                 !StrRangeToUint(numberRange2, range.second) ||
356                 range.second < range.first)
357             {
358                 return false;
359             }
360             m_Ranges.push_back(range);
361         }
362 
363         // Skip ','
364         currRange.beg = currRange.end + 1;
365     }
366 
367     return true;
368 }
369 
370 template<typename T>
Includes(T number)371 bool RangeSequence<T>::Includes(T number) const
372 {
373     for(const auto& it : m_Ranges)
374     {
375         if(number >= it.first && number <= it.second)
376         {
377             return true;
378         }
379     }
380     return false;
381 }
382 
383 /*
384 class RandomNumberGenerator
385 {
386 public:
387     RandomNumberGenerator() : m_Value{GetTickCount()} {}
388     RandomNumberGenerator(uint32_t seed) : m_Value{seed} { }
389     void Seed(uint32_t seed) { m_Value = seed; }
390     uint32_t Generate() { return GenerateFast() ^ (GenerateFast() >> 7); }
391 
392 private:
393     uint32_t m_Value;
394     uint32_t GenerateFast() { return m_Value = (m_Value * 196314165 + 907633515); }
395 };
396 
397 enum class CONSOLE_COLOR
398 {
399     INFO,
400     NORMAL,
401     WARNING,
402     ERROR_,
403     COUNT
404 };
405 
406 void SetConsoleColor(CONSOLE_COLOR color);
407 
408 void PrintMessage(CONSOLE_COLOR color, const char* msg);
409 void PrintMessage(CONSOLE_COLOR color, const wchar_t* msg);
410 
411 inline void Print(const char* msg) { PrintMessage(CONSOLE_COLOR::NORMAL, msg); }
412 inline void Print(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::NORMAL, msg); }
413 inline void PrintWarning(const char* msg) { PrintMessage(CONSOLE_COLOR::WARNING, msg); }
414 inline void PrintWarning(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::WARNING, msg); }
415 inline void PrintError(const char* msg) { PrintMessage(CONSOLE_COLOR::ERROR_, msg); }
416 inline void PrintError(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::ERROR_, msg); }
417 
418 void PrintMessageV(CONSOLE_COLOR color, const char* format, va_list argList);
419 void PrintMessageV(CONSOLE_COLOR color, const wchar_t* format, va_list argList);
420 void PrintMessageF(CONSOLE_COLOR color, const char* format, ...);
421 void PrintMessageF(CONSOLE_COLOR color, const wchar_t* format, ...);
422 void PrintWarningF(const char* format, ...);
423 void PrintWarningF(const wchar_t* format, ...);
424 void PrintErrorF(const char* format, ...);
425 void PrintErrorF(const wchar_t* format, ...);
426 */
427