params.py (7534:c76a14014c27) | params.py (7673:b28bd1fa9a35) |
---|---|
1# Copyright (c) 2004-2006 The Regents of The University of Michigan 2# Copyright (c) 2010 Advanced Micro Devices, Inc. 3# All rights reserved. 4# 5# Redistribution and use in source and binary forms, with or without 6# modification, are permitted provided that the following conditions are 7# met: redistributions of source code must retain the above copyright 8# notice, this list of conditions and the following disclaimer; --- 66 unchanged lines hidden (view full) --- 75 return cls 76 77 78# Dummy base class to identify types that are legitimate for SimObject 79# parameters. 80class ParamValue(object): 81 __metaclass__ = MetaParamValue 82 | 1# Copyright (c) 2004-2006 The Regents of The University of Michigan 2# Copyright (c) 2010 Advanced Micro Devices, Inc. 3# All rights reserved. 4# 5# Redistribution and use in source and binary forms, with or without 6# modification, are permitted provided that the following conditions are 7# met: redistributions of source code must retain the above copyright 8# notice, this list of conditions and the following disclaimer; --- 66 unchanged lines hidden (view full) --- 75 return cls 76 77 78# Dummy base class to identify types that are legitimate for SimObject 79# parameters. 80class ParamValue(object): 81 __metaclass__ = MetaParamValue 82 |
83 cxx_predecls = [] 84 swig_predecls = [] | 83 @classmethod 84 def cxx_predecls(cls, code): 85 pass |
85 | 86 |
87 @classmethod 88 def swig_predecls(cls, code): 89 pass 90 |
|
86 # default for printing to .ini file is regular string conversion. 87 # will be overridden in some cases 88 def ini_str(self): 89 return str(self) 90 91 # allows us to blithely call unproxy() on things without checking 92 # if they're really proxies or not 93 def unproxy(self, base): --- 53 unchanged lines hidden (view full) --- 147 # we're just assigning a null pointer 148 return value 149 if isinstance(value, self.ptype): 150 return value 151 if isNullPointer(value) and isSimObjectClass(self.ptype): 152 return value 153 return self.ptype(value) 154 | 91 # default for printing to .ini file is regular string conversion. 92 # will be overridden in some cases 93 def ini_str(self): 94 return str(self) 95 96 # allows us to blithely call unproxy() on things without checking 97 # if they're really proxies or not 98 def unproxy(self, base): --- 53 unchanged lines hidden (view full) --- 152 # we're just assigning a null pointer 153 return value 154 if isinstance(value, self.ptype): 155 return value 156 if isNullPointer(value) and isSimObjectClass(self.ptype): 157 return value 158 return self.ptype(value) 159 |
155 def cxx_predecls(self): 156 return self.ptype.cxx_predecls | 160 def cxx_predecls(self, code): 161 self.ptype.cxx_predecls(code) |
157 | 162 |
158 def swig_predecls(self): 159 return self.ptype.swig_predecls | 163 def swig_predecls(self, code): 164 self.ptype.swig_predecls(code) |
160 | 165 |
161 def cxx_decl(self): 162 return '%s %s;' % (self.ptype.cxx_type, self.name) | 166 def cxx_decl(self, code): 167 code('${{self.ptype.cxx_type}} ${{self.name}};') |
163 164# Vector-valued parameter description. Just like ParamDesc, except 165# that the value is a vector (list) of the specified type instead of a 166# single value. 167 168class VectorParamValue(list): 169 __metaclass__ = MetaParamValue 170 def __setattr__(self, attr, value): --- 59 unchanged lines hidden (view full) --- 230 # singleton: coerce to a single-element list 231 tmp_list = [ ParamDesc.convert(self, value) ] 232 233 if isSimObjectSequence(tmp_list): 234 return SimObjectVector(tmp_list) 235 else: 236 return VectorParamValue(tmp_list) 237 | 168 169# Vector-valued parameter description. Just like ParamDesc, except 170# that the value is a vector (list) of the specified type instead of a 171# single value. 172 173class VectorParamValue(list): 174 __metaclass__ = MetaParamValue 175 def __setattr__(self, attr, value): --- 59 unchanged lines hidden (view full) --- 235 # singleton: coerce to a single-element list 236 tmp_list = [ ParamDesc.convert(self, value) ] 237 238 if isSimObjectSequence(tmp_list): 239 return SimObjectVector(tmp_list) 240 else: 241 return VectorParamValue(tmp_list) 242 |
238 def swig_predecls(self): 239 return ['%%include "%s_vptype.i"' % self.ptype_str] | 243 def swig_predecls(self, code): 244 code('%include "${{self.ptype_str}}_vptype.i"') |
240 | 245 |
241 def swig_decl(self): | 246 def swig_decl(self, code): |
242 cxx_type = re.sub('std::', '', self.ptype.cxx_type) | 247 cxx_type = re.sub('std::', '', self.ptype.cxx_type) |
243 vdecl = 'namespace std { %%template(vector_%s) vector< %s >; }' % \ 244 (self.ptype_str, cxx_type) 245 return ['%include "std_vector.i"'] + self.ptype.swig_predecls + [vdecl] | 248 code('%include "std_vector.i"') 249 self.ptype.swig_predecls(code) 250 code('''\ 251namespace std { 252%template(vector_${{self.ptype_str}}) vector< $cxx_type >; 253} 254''') |
246 | 255 |
247 def cxx_predecls(self): 248 return ['#include <vector>'] + self.ptype.cxx_predecls | 256 def cxx_predecls(self, code): 257 code('#include <vector>') 258 self.ptype.cxx_predecls(code) |
249 | 259 |
250 def cxx_decl(self): 251 return 'std::vector< %s > %s;' % (self.ptype.cxx_type, self.name) | 260 def cxx_decl(self, code): 261 code('std::vector< ${{self.ptype.cxx_type}} > ${{self.name}};') |
252 253class ParamFactory(object): 254 def __init__(self, param_desc_class, ptype_str = None): 255 self.param_desc_class = param_desc_class 256 self.ptype_str = ptype_str 257 258 def __getattr__(self, attr): 259 if self.ptype_str: --- 26 unchanged lines hidden (view full) --- 286# the __str__() conversion method). 287# 288##################################################################### 289 290# String-valued parameter. Just mixin the ParamValue class with the 291# built-in str class. 292class String(ParamValue,str): 293 cxx_type = 'std::string' | 262 263class ParamFactory(object): 264 def __init__(self, param_desc_class, ptype_str = None): 265 self.param_desc_class = param_desc_class 266 self.ptype_str = ptype_str 267 268 def __getattr__(self, attr): 269 if self.ptype_str: --- 26 unchanged lines hidden (view full) --- 296# the __str__() conversion method). 297# 298##################################################################### 299 300# String-valued parameter. Just mixin the ParamValue class with the 301# built-in str class. 302class String(ParamValue,str): 303 cxx_type = 'std::string' |
294 cxx_predecls = ['#include <string>'] 295 swig_predecls = ['%include "std_string.i"\n' + 296 '%apply const std::string& {std::string *};'] 297 swig_predecls = ['%include "std_string.i"' ] | |
298 | 304 |
305 @classmethod 306 def cxx_predecls(self, code): 307 code('#include <string>') 308 309 @classmethod 310 def swig_predecls(cls, code): 311 code('%include "std_string.i"') 312 |
|
299 def getValue(self): 300 return self 301 302# superclass for "numeric" parameter values, to emulate math 303# operations in a type-safe way. e.g., a Latency times an int returns 304# a new Latency object. 305class NumericParamValue(ParamValue): 306 def __str__(self): --- 38 unchanged lines hidden (view full) --- 345 super(CheckedIntType, cls).__init__(name, bases, dict) 346 347 # CheckedInt is an abstract base class, so we actually don't 348 # want to do any processing on it... the rest of this code is 349 # just for classes that derive from CheckedInt. 350 if name == 'CheckedInt': 351 return 352 | 313 def getValue(self): 314 return self 315 316# superclass for "numeric" parameter values, to emulate math 317# operations in a type-safe way. e.g., a Latency times an int returns 318# a new Latency object. 319class NumericParamValue(ParamValue): 320 def __str__(self): --- 38 unchanged lines hidden (view full) --- 359 super(CheckedIntType, cls).__init__(name, bases, dict) 360 361 # CheckedInt is an abstract base class, so we actually don't 362 # want to do any processing on it... the rest of this code is 363 # just for classes that derive from CheckedInt. 364 if name == 'CheckedInt': 365 return 366 |
353 if not cls.cxx_predecls: 354 # most derived types require this, so we just do it here once 355 cls.cxx_predecls = ['#include "base/types.hh"'] 356 357 if not cls.swig_predecls: 358 # most derived types require this, so we just do it here once 359 cls.swig_predecls = ['%import "stdint.i"\n' + 360 '%import "base/types.hh"'] 361 | |
362 if not (hasattr(cls, 'min') and hasattr(cls, 'max')): 363 if not (hasattr(cls, 'size') and hasattr(cls, 'unsigned')): 364 panic("CheckedInt subclass %s must define either\n" \ 365 " 'min' and 'max' or 'size' and 'unsigned'\n", 366 name); 367 if cls.unsigned: 368 cls.min = 0 369 cls.max = 2 ** cls.size - 1 --- 18 unchanged lines hidden (view full) --- 388 self.value = convert.toInteger(value) 389 elif isinstance(value, (int, long, float, NumericParamValue)): 390 self.value = long(value) 391 else: 392 raise TypeError, "Can't convert object of type %s to CheckedInt" \ 393 % type(value).__name__ 394 self._check() 395 | 367 if not (hasattr(cls, 'min') and hasattr(cls, 'max')): 368 if not (hasattr(cls, 'size') and hasattr(cls, 'unsigned')): 369 panic("CheckedInt subclass %s must define either\n" \ 370 " 'min' and 'max' or 'size' and 'unsigned'\n", 371 name); 372 if cls.unsigned: 373 cls.min = 0 374 cls.max = 2 ** cls.size - 1 --- 18 unchanged lines hidden (view full) --- 393 self.value = convert.toInteger(value) 394 elif isinstance(value, (int, long, float, NumericParamValue)): 395 self.value = long(value) 396 else: 397 raise TypeError, "Can't convert object of type %s to CheckedInt" \ 398 % type(value).__name__ 399 self._check() 400 |
401 @classmethod 402 def cxx_predecls(cls, code): 403 # most derived types require this, so we just do it here once 404 code('#include "base/types.hh"') 405 406 @classmethod 407 def swig_predecls(cls, code): 408 # most derived types require this, so we just do it here once 409 code('%import "stdint.i"') 410 code('%import "base/types.hh"') 411 |
|
396 def getValue(self): 397 return long(self.value) 398 399class Int(CheckedInt): cxx_type = 'int'; size = 32; unsigned = False 400class Unsigned(CheckedInt): cxx_type = 'unsigned'; size = 32; unsigned = True 401 402class Int8(CheckedInt): cxx_type = 'int8_t'; size = 8; unsigned = False 403class UInt8(CheckedInt): cxx_type = 'uint8_t'; size = 8; unsigned = True --- 67 unchanged lines hidden (view full) --- 471 472 473class MetaRange(MetaParamValue): 474 def __init__(cls, name, bases, dict): 475 super(MetaRange, cls).__init__(name, bases, dict) 476 if name == 'Range': 477 return 478 cls.cxx_type = 'Range< %s >' % cls.type.cxx_type | 412 def getValue(self): 413 return long(self.value) 414 415class Int(CheckedInt): cxx_type = 'int'; size = 32; unsigned = False 416class Unsigned(CheckedInt): cxx_type = 'unsigned'; size = 32; unsigned = True 417 418class Int8(CheckedInt): cxx_type = 'int8_t'; size = 8; unsigned = False 419class UInt8(CheckedInt): cxx_type = 'uint8_t'; size = 8; unsigned = True --- 67 unchanged lines hidden (view full) --- 487 488 489class MetaRange(MetaParamValue): 490 def __init__(cls, name, bases, dict): 491 super(MetaRange, cls).__init__(name, bases, dict) 492 if name == 'Range': 493 return 494 cls.cxx_type = 'Range< %s >' % cls.type.cxx_type |
479 cls.cxx_predecls = \ 480 ['#include "base/range.hh"'] + cls.type.cxx_predecls | |
481 482class Range(ParamValue): 483 __metaclass__ = MetaRange 484 type = Int # default; can be overridden in subclasses 485 def __init__(self, *args, **kwargs): 486 def handle_kwargs(self, kwargs): 487 if 'end' in kwargs: 488 self.second = self.type(kwargs.pop('end')) --- 27 unchanged lines hidden (view full) --- 516 raise TypeError, "Too many arguments specified" 517 518 if kwargs: 519 raise TypeError, "too many keywords: %s" % kwargs.keys() 520 521 def __str__(self): 522 return '%s:%s' % (self.first, self.second) 523 | 495 496class Range(ParamValue): 497 __metaclass__ = MetaRange 498 type = Int # default; can be overridden in subclasses 499 def __init__(self, *args, **kwargs): 500 def handle_kwargs(self, kwargs): 501 if 'end' in kwargs: 502 self.second = self.type(kwargs.pop('end')) --- 27 unchanged lines hidden (view full) --- 530 raise TypeError, "Too many arguments specified" 531 532 if kwargs: 533 raise TypeError, "too many keywords: %s" % kwargs.keys() 534 535 def __str__(self): 536 return '%s:%s' % (self.first, self.second) 537 |
538 @classmethod 539 def cxx_predecls(cls, code): 540 code('#include "base/range.hh"') 541 cls.type.cxx_predecls(code) 542 |
|
524class AddrRange(Range): 525 type = Addr | 543class AddrRange(Range): 544 type = Addr |
526 swig_predecls = ['%include "python/swig/range.i"'] | |
527 | 545 |
546 @classmethod 547 def swig_predecls(cls, code): 548 code('%include "python/swig/range.i"') 549 |
|
528 def getValue(self): 529 from m5.objects.params import AddrRange 530 531 value = AddrRange() 532 value.start = long(self.first) 533 value.end = long(self.second) 534 return value 535 536class TickRange(Range): 537 type = Tick | 550 def getValue(self): 551 from m5.objects.params import AddrRange 552 553 value = AddrRange() 554 value.start = long(self.first) 555 value.end = long(self.second) 556 return value 557 558class TickRange(Range): 559 type = Tick |
538 swig_predecls = ['%include "python/swig/range.i"'] | |
539 | 560 |
561 @classmethod 562 def swig_predecls(cls, code): 563 code('%include "python/swig/range.i"') 564 |
|
540 def getValue(self): 541 from m5.objects.params import TickRange 542 543 value = TickRange() 544 value.start = long(self.first) 545 value.end = long(self.second) 546 return value 547 --- 36 unchanged lines hidden (view full) --- 584 global _NextEthernetAddr 585 586 value = _NextEthernetAddr 587 _NextEthernetAddr = IncEthernetAddr(_NextEthernetAddr, 1) 588 return value 589 590class EthernetAddr(ParamValue): 591 cxx_type = 'Net::EthAddr' | 565 def getValue(self): 566 from m5.objects.params import TickRange 567 568 value = TickRange() 569 value.start = long(self.first) 570 value.end = long(self.second) 571 return value 572 --- 36 unchanged lines hidden (view full) --- 609 global _NextEthernetAddr 610 611 value = _NextEthernetAddr 612 _NextEthernetAddr = IncEthernetAddr(_NextEthernetAddr, 1) 613 return value 614 615class EthernetAddr(ParamValue): 616 cxx_type = 'Net::EthAddr' |
592 cxx_predecls = ['#include "base/inet.hh"'] 593 swig_predecls = ['%include "python/swig/inet.i"'] | 617 618 @classmethod 619 def cxx_predecls(cls, code): 620 code('#include "base/inet.hh"') 621 622 @classmethod 623 def swig_predecls(cls, code): 624 code('%include "python/swig/inet.i"') 625 |
594 def __init__(self, value): 595 if value == NextEthernetAddr: 596 self.value = value 597 return 598 599 if not isinstance(value, str): 600 raise TypeError, "expected an ethernet address and didn't get one" 601 --- 54 unchanged lines hidden (view full) --- 656 return strptime(value, format) 657 except ValueError: 658 pass 659 660 raise ValueError, "Could not parse '%s' as a time" % value 661 662class Time(ParamValue): 663 cxx_type = 'tm' | 626 def __init__(self, value): 627 if value == NextEthernetAddr: 628 self.value = value 629 return 630 631 if not isinstance(value, str): 632 raise TypeError, "expected an ethernet address and didn't get one" 633 --- 54 unchanged lines hidden (view full) --- 688 return strptime(value, format) 689 except ValueError: 690 pass 691 692 raise ValueError, "Could not parse '%s' as a time" % value 693 694class Time(ParamValue): 695 cxx_type = 'tm' |
664 cxx_predecls = [ '#include <time.h>' ] 665 swig_predecls = [ '%include "python/swig/time.i"' ] | 696 697 @classmethod 698 def cxx_predecls(cls, code): 699 code('#include <time.h>') 700 701 @classmethod 702 def swig_predecls(cls, code): 703 code('%include "python/swig/time.i"') 704 |
666 def __init__(self, value): 667 self.value = parse_time(value) 668 669 def getValue(self): 670 from m5.objects.params import tm 671 672 c_time = tm() 673 py_time = self.value --- 70 unchanged lines hidden (view full) --- 744 745 cls.cxx_type = 'Enums::%s' % name 746 747 super(MetaEnum, cls).__init__(name, bases, init_dict) 748 749 # Generate C++ class declaration for this enum type. 750 # Note that we wrap the enum in a class/struct to act as a namespace, 751 # so that the enum strings can be brief w/o worrying about collisions. | 705 def __init__(self, value): 706 self.value = parse_time(value) 707 708 def getValue(self): 709 from m5.objects.params import tm 710 711 c_time = tm() 712 py_time = self.value --- 70 unchanged lines hidden (view full) --- 783 784 cls.cxx_type = 'Enums::%s' % name 785 786 super(MetaEnum, cls).__init__(name, bases, init_dict) 787 788 # Generate C++ class declaration for this enum type. 789 # Note that we wrap the enum in a class/struct to act as a namespace, 790 # so that the enum strings can be brief w/o worrying about collisions. |
752 def cxx_decl(cls): | 791 def cxx_decl(cls, code): |
753 name = cls.__name__ | 792 name = cls.__name__ |
754 code = "#ifndef __ENUM__%s\n" % name 755 code += '#define __ENUM__%s\n' % name 756 code += '\n' 757 code += 'namespace Enums {\n' 758 code += ' enum %s {\n' % name | 793 code('''\ 794#ifndef __ENUM__${name}__ 795#define __ENUM__${name}__ 796 797namespace Enums { 798 enum $name { 799''') 800 code.indent(2) |
759 for val in cls.vals: | 801 for val in cls.vals: |
760 code += ' %s = %d,\n' % (val, cls.map[val]) 761 code += ' Num_%s = %d,\n' % (name, len(cls.vals)) 762 code += ' };\n' 763 code += ' extern const char *%sStrings[Num_%s];\n' % (name, name) 764 code += '}\n' 765 code += '\n' 766 code += '#endif\n' 767 return code | 802 code('$val = ${{cls.map[val]}},') 803 code('Num_$name = ${{len(cls.vals)}},') 804 code.dedent(2) 805 code('''\ 806 }; 807extern const char *${name}Strings[Num_${name}]; 808} |
768 | 809 |
769 def cxx_def(cls): | 810#endif // __ENUM__${name}__ 811''') 812 813 def cxx_def(cls, code): |
770 name = cls.__name__ | 814 name = cls.__name__ |
771 code = '#include "enums/%s.hh"\n' % name 772 code += 'namespace Enums {\n' 773 code += ' const char *%sStrings[Num_%s] =\n' % (name, name) 774 code += ' {\n' | 815 code('''\ 816#include "enums/${name}.hh" 817namespace Enums { 818 const char *${name}Strings[Num_${name}] = 819 { 820''') 821 code.indent(2) |
775 for val in cls.vals: | 822 for val in cls.vals: |
776 code += ' "%s",\n' % val 777 code += ' };\n' 778 code += '}\n' 779 return code | 823 code('"$val",') 824 code.dedent(2) 825 code(''' 826 }; 827/* namespace Enums */ } 828''') |
780 781# Base class for enum types. 782class Enum(ParamValue): 783 __metaclass__ = MetaEnum 784 vals = [] 785 786 def __init__(self, value): 787 if value not in self.map: --- 7 unchanged lines hidden (view full) --- 795 def __str__(self): 796 return self.value 797 798# how big does a rounding error need to be before we warn about it? 799frequency_tolerance = 0.001 # 0.1% 800 801class TickParamValue(NumericParamValue): 802 cxx_type = 'Tick' | 829 830# Base class for enum types. 831class Enum(ParamValue): 832 __metaclass__ = MetaEnum 833 vals = [] 834 835 def __init__(self, value): 836 if value not in self.map: --- 7 unchanged lines hidden (view full) --- 844 def __str__(self): 845 return self.value 846 847# how big does a rounding error need to be before we warn about it? 848frequency_tolerance = 0.001 # 0.1% 849 850class TickParamValue(NumericParamValue): 851 cxx_type = 'Tick' |
803 cxx_predecls = ['#include "base/types.hh"'] 804 swig_predecls = ['%import "stdint.i"\n' + 805 '%import "base/types.hh"'] | |
806 | 852 |
853 @classmethod 854 def cxx_predecls(cls, code): 855 code('#include "base/types.hh"') 856 857 @classmethod 858 def swig_predecls(cls, code): 859 code('%import "stdint.i"') 860 code('%import "base/types.hh"') 861 |
|
807 def getValue(self): 808 return long(self.value) 809 810class Latency(TickParamValue): 811 def __init__(self, value): 812 if isinstance(value, (Latency, Clock)): 813 self.ticks = value.ticks 814 self.value = value.value --- 58 unchanged lines hidden (view full) --- 873 def ini_str(self): 874 return '%d' % self.getValue() 875 876# A generic frequency and/or Latency value. Value is stored as a latency, 877# but to avoid ambiguity this object does not support numeric ops (* or /). 878# An explicit conversion to a Latency or Frequency must be made first. 879class Clock(ParamValue): 880 cxx_type = 'Tick' | 862 def getValue(self): 863 return long(self.value) 864 865class Latency(TickParamValue): 866 def __init__(self, value): 867 if isinstance(value, (Latency, Clock)): 868 self.ticks = value.ticks 869 self.value = value.value --- 58 unchanged lines hidden (view full) --- 928 def ini_str(self): 929 return '%d' % self.getValue() 930 931# A generic frequency and/or Latency value. Value is stored as a latency, 932# but to avoid ambiguity this object does not support numeric ops (* or /). 933# An explicit conversion to a Latency or Frequency must be made first. 934class Clock(ParamValue): 935 cxx_type = 'Tick' |
881 cxx_predecls = ['#include "base/types.hh"'] 882 swig_predecls = ['%import "stdint.i"\n' + 883 '%import "base/types.hh"'] | 936 937 @classmethod 938 def cxx_predecls(cls, code): 939 code('#include "base/types.hh"') 940 941 @classmethod 942 def swig_predecls(cls, code): 943 code('%import "stdint.i"') 944 code('%import "base/types.hh"') 945 |
884 def __init__(self, value): 885 if isinstance(value, (Latency, Clock)): 886 self.ticks = value.ticks 887 self.value = value.value 888 elif isinstance(value, Frequency): 889 self.ticks = value.ticks 890 self.value = 1.0 / value.value 891 elif value.endswith('t'): --- 346 unchanged lines hidden --- | 946 def __init__(self, value): 947 if isinstance(value, (Latency, Clock)): 948 self.ticks = value.ticks 949 self.value = value.value 950 elif isinstance(value, Frequency): 951 self.ticks = value.ticks 952 self.value = 1.0 / value.value 953 elif value.endswith('t'): --- 346 unchanged lines hidden --- |