That would work, but we don't have includes in the middle of a class like that anywhere else in gem5 (that I can remember at least), which I think is for the best :-).
Gabe On Thu, Oct 22, 2020 at 6:28 PM Gambord, Ryan via gem5-dev < gem5-dev@gem5.org> wrote: > @Gabe Black <gabebl...@google.com> > Here is an example of what this looks like. It requires slightly modifying > the boilerplate code generated for params structs, and then moving the > include from the top of the source file to inside the class. This brings > the struct into the class namespace. > > This should work fine as long as pybind can work with a FQN of an object. > > MySimObject.hh > #ifndef __MYSIMOBJECT_HH__ > #define __MYSIMOBJECT_HH__ > > class MySimObject > { > public: > #include "MySimObjectParams.hh" > > public: > MySimObject(Params * p) : myint(p->myint) {} > > int & myInt() { return myint; } > > private: > int myint; > }; > #endif // __MYSIMOBJECT_HH__ > > MySimObjectParams.hh > // Generated automatically by SCons // > > struct Params { > int myint; > }; > > main.cc > #include <iostream> > #include <cstdlib> > > #include "MySimObject.hh" > > int > main( int argc, char *argv[]){ > MySimObject::Params p; > p.myint = 5; > MySimObject my_so_instance(&p); > std::cout << my_so_instance.myInt() << std::endl; > return EXIT_SUCCESS; > } > > Ryan Gambord > <gambo...@oregonstate.edu> > > > > On Thu, Oct 22, 2020 at 5:20 PM Gabe Black via gem5-dev <gem5-dev@gem5.org> > wrote: > >> [This email originated from outside of OSU. Use caution with links and >> attachments.] >> I definitely agree that we need to use more namespaces and be better >> citizens in the global namespace. >> >> See https://gem5.atlassian.net/browse/GEM5-730 >> >> Mechanically, I don't think we can define something like >> Mem::Ruby::Network::BasicLink::Params since that would require adding a >> Params type to the not yet defined BasicLink class. You can do that with >> namespaces, but not with classes. We also couldn't add a params function to >> the SimObject for the same reason. Python doesn't define the SimObject >> class at all, even though it might look like it does because the python >> objects and C++ objects often (but not always) share the same name. The >> Python objects actually are the Params structs in C++, and then python uses >> the create method to make the actual SimObjects. The real C++ SimObject >> classes have no python analogue, although python has pointers to them and >> can indirectly call methods on them once they've been instantiated. That's >> how callbacks like init(), startup(), etc are handled. >> >> Gabe >> >> On Thu, Oct 22, 2020 at 10:25 AM Gambord, Ryan via gem5-dev < >> gem5-dev@gem5.org> wrote: >> >>> While we're thinking about the params implementations, I'd also like to >>> propose that we stop cluttering the global namespace with collision-prone >>> names: >>> >>> src/.../.../MySimObject.hh >>> namespace NoClutter { >>> class MySimObject : ::SimObject >>> { >>> #include params/MySimObject.hh >>> }; >>> }; >>> >>> params/MySimObject.hh >>> // ... // >>> struct Params { >>> // ... // >>> }; >>> >>> For example, ruby claimed the name "BasicLink", which is pretty generic. >>> Would be much better if we started moving towards >>> Mem::Ruby::Network::BasicLink::Params, which would be more idiomatic C++. >>> The params/xxx.hh sources could even include the boilerplate params() >>> method into the simobject class if you want. There is *the* canonical >>> use-case for mid-file includes -- when we have compile-time generated >>> boilerplate in separate sources. >>> >>> Right now, gem5 gives me "C with classes" vibes. >>> >>> Ryan Gambord >>> <gambo...@oregonstate.edu> >>> >>> >>> >>> On Thu, Oct 22, 2020 at 9:18 AM Jason Lowe-Power via gem5-dev < >>> gem5-dev@gem5.org> wrote: >>> >>>> [This email originated from outside of OSU. Use caution with links and >>>> attachments.] >>>> Another simple proposal: >>>> - Remove params() from the API (with deprecation) >>>> - Update objects that can easily be updated and remove the params() >>>> calls/casts. I think this is most cases of the params use outside of the >>>> constructor. >>>> - Don't worry about the others that use the params() function in many >>>> places that require deeper updates >>>> - Update the documentation to say that the "best practice" is to not >>>> use the param function >>>> - In the future, make sure that new objects don't store the params >>>> object. >>>> >>>> Cheers, >>>> Jason >>>> >>>> On Thu, Oct 22, 2020 at 8:51 AM Giacomo Travaglini < >>>> giacomo.travagl...@arm.com> wrote: >>>> >>>>> Let me add to the plate a simple proposal though still a bit verbose >>>>> and probably not that different from a manual cast >>>>> >>>>> >>>>> >>>>> Defining a template method in SimObject: >>>>> >>>>> >>>>> >>>>> *template <class Obj>* >>>>> >>>>> *Obj params()* >>>>> >>>>> >>>>> *{ return static_cast<Obj>(_params);* >>>>> >>>>> * Or more secure:* >>>>> >>>>> * param = dynamic_cast<Obj>(_params);* >>>>> >>>>> * assert(param);* >>>>> >>>>> * return param;* >>>>> >>>>> *}* >>>>> >>>>> >>>>> >>>>> And delegate the type specification on the client side: >>>>> >>>>> >>>>> >>>>> For example in my shiny new >>>>> >>>>> >>>>> >>>>> Class MyObject : public SimObject {} >>>>> >>>>> >>>>> >>>>> I would use >>>>> >>>>> >>>>> >>>>> auto p = params<MyObjectParams*>(); >>>>> >>>>> >>>>> >>>>> You still have to type your param type so that doesn’t make it the >>>>> best but I believe it’s the simplest one >>>>> >>>>> >>>>> >>>>> Giacomo >>>>> >>>>> >>>>> >>>>> *From:* Jason Lowe-Power via gem5-dev <gem5-dev@gem5.org> >>>>> *Sent:* 22 October 2020 16:26 >>>>> *To:* gem5 Developer List <gem5-dev@gem5.org> >>>>> *Cc:* Gabe Black <gabe.bl...@gmail.com>; Jason Lowe-Power < >>>>> ja...@lowepower.com> >>>>> *Subject:* [gem5-dev] Re: SimObject params() method >>>>> >>>>> >>>>> >>>>> Hey Gabe, >>>>> >>>>> >>>>> >>>>> Thanks for bringing this up. I have also been bothered by the lack of >>>>> consistency with how params are used. I can't think of an example of when >>>>> you need to store the params object. I would be all for getting rid of the >>>>> params() function and updating the documentation to say that it's best >>>>> practice to *not* save the params struct after the constructor. If some >>>>> object had a good reason to go against this best practice, that would be >>>>> OK, and we wouldn't need to enforce any specific design or pattern on >>>>> these >>>>> exceptions. I would prefer to remove the params() function than add more >>>>> template magic. >>>>> >>>>> >>>>> >>>>> On Thu, Oct 22, 2020 at 1:18 AM Gabe Black via gem5-dev < >>>>> gem5-dev@gem5.org> wrote: >>>>> >>>>> Hi folks. I'm looking at the SimObject header, and I see a few things >>>>> in there which are marked as part of the API and maybe shouldn't be. >>>>> Specifically I'm talking about the Params typedef, and the params() >>>>> method. >>>>> There is also the _params member variable which I can see being a part of >>>>> the API since it can be used by other classes to make their own params() >>>>> function (more on that below), but the Params typedef is more or less an >>>>> implementation detail, and the params() method is essentially worthless >>>>> because it returns a SimObjectParams which doesn't have anything except >>>>> the >>>>> object's name in it, and you can already get that with the name() method. >>>>> >>>>> >>>>> >>>>> I agree. I think the typedef is useless and shouldn't be in the API. >>>>> It's unfortunate that the API proposals didn't get more reviews. I think >>>>> it's probably OK to just drop that from the API, but the params() function >>>>> itself is going to need to be deprecated. >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> *Params pattern* >>>>> >>>>> >>>>> >>>>> This gets to the whole Params params() pattern which is sporadically >>>>> implemented in some SimObjects in gem5. This pattern is that a given >>>>> SimObject subclass will define a Params typedef which corresponds to its >>>>> Params struct type, and then also define a params() method which returns >>>>> the _params from SimObject cast up to that type. >>>>> >>>>> >>>>> >>>>> The Params typedef itself primarily makes the definition of the >>>>> constructor a little more legible, since the FullFooTypeForTheArmISAParams >>>>> can be really verbose. >>>>> >>>>> >>>>> >>>>> I think verbose is fine. I would vote to abolish all params typedefs. >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> Storing the params struct itself could theoretically serve the purpose >>>>> of having a bunch of parameters and not having to create a member variable >>>>> for each one, spend a bunch of text copying values over in the >>>>> constructor, >>>>> etc. I think most of the time this is unnecessary, but if an object has >>>>> tons of values in it for some reason this could make sense. >>>>> >>>>> >>>>> >>>>> I don't think there are any examples of this in the codebase. I think >>>>> in all cases the params data is copied into member variables. If there are >>>>> cases where data isn't copied, I doubt it was with a strong reason in >>>>> mind. >>>>> The one exception to this might be Ruby, but it's an exception for all the >>>>> wrong reasons ;). >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> The params() method then makes the _params member available with the >>>>> appropriate type, so that all the FooParams members are accessible. It >>>>> also >>>>> makes the params struct accessible outside the object which is used in a >>>>> place or two to read parameters without there needing to be a member in >>>>> the >>>>> object, and probably some sort of accessor to read it. >>>>> >>>>> >>>>> >>>>> There are two main problems with this system. First, when used, it >>>>> adds a small but not trivial amount of boilerplate to any given class. >>>>> Second, it's very sporadically implemented. I think in a lot of places >>>>> it's >>>>> there just because people aren't sure what it's for or if they need it, so >>>>> they just put one there regardless. I think I've done that in the past. >>>>> >>>>> >>>>> >>>>> *Alternative* >>>>> >>>>> >>>>> >>>>> The existence of the Params type and the params() method could be >>>>> partially eliminated by defining a templated params() method which took a >>>>> SimObject reference and/or pointer as its first parameter. It could then >>>>> figure out what Params struct went with that SimObject type using >>>>> typedef/template magic set up by the Params building code, and then >>>>> perform >>>>> the appropriate cast. >>>>> >>>>> >>>>> >>>>> This has three downsides, two minor and one more serious. The minor >>>>> one is that when a class uses this method internally, it would have to do >>>>> something like params(this) instead of just params(). That's a fairly >>>>> minor >>>>> difference and not that big a deal. For external consumers that would be >>>>> less of a problem since it would change from foo->params() to params(foo). >>>>> >>>>> >>>>> >>>>> The second minor issue is that the name params() is very short, and >>>>> likely to collide with other names. We could define that with SimObject as >>>>> a static method, but then that would make foo->params() turn into the more >>>>> verbose SimObject::params(foo), or (and I haven't checked if this is legal >>>>> syntax) the more odd looking foo->params(foo). The params() class can't be >>>>> a non-static method, because then the type of "this" would be fixed by >>>>> where it was defined, meaning it would not cast _params to the right type. >>>>> I was not able to find any mechanism in c++ that would let you treat >>>>> "this" >>>>> as an argument for template type resolution. >>>>> >>>>> >>>>> >>>>> The third more serious problem is that this implicitly breaks the >>>>> ability to use two different SimObject types in python to represent the >>>>> same SimObject type in C++. I don't know if this happens in practice, and >>>>> it's also broken by the original Params pattern, since there can be only >>>>> one typedef in a given class. Since Params is applied adhoc manually, >>>>> something that is generally not good, it actually avoids this problem by >>>>> just not existing anywhere that would break that assumption. >>>>> >>>>> >>>>> >>>>> *Other option* >>>>> >>>>> >>>>> >>>>> Another option would be to have a templated class which would define a >>>>> Params type and a params() method, and inherit that into each SimObject >>>>> which wants to have those members. It would itself inherit from its >>>>> parameter which would keep the inheritance hierarchy intact, and make it >>>>> possible to override Params and params from super classes: >>>>> >>>>> >>>>> >>>>> FooObject : public ParamsMembers<SimObject> >>>>> >>>>> >>>>> >>>>> This has a similar problem to the above if exactly what Params type to >>>>> use is automatic, although here it could be an additional template >>>>> argument. This also trades some boilerplate for less boilerplate, has to >>>>> be >>>>> applied manually to any classes that want to take advantage of it, and >>>>> obfuscates the definition of those classes. >>>>> >>>>> >>>>> >>>>> Gabe >>>>> >>>>> _______________________________________________ >>>>> gem5-dev mailing list -- gem5-dev@gem5.org >>>>> To unsubscribe send an email to gem5-dev-le...@gem5.org >>>>> %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s >>>>> >>>>> IMPORTANT NOTICE: The contents of this email and any attachments are >>>>> confidential and may also be privileged. If you are not the intended >>>>> recipient, please notify the sender immediately and do not disclose the >>>>> contents to any other person, use it for any purpose, or store or copy the >>>>> information in any medium. Thank you. >>>>> >>>> _______________________________________________ >>>> gem5-dev mailing list -- gem5-dev@gem5.org >>>> To unsubscribe send an email to gem5-dev-le...@gem5.org >>>> %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s >>> >>> _______________________________________________ >>> gem5-dev mailing list -- gem5-dev@gem5.org >>> To unsubscribe send an email to gem5-dev-le...@gem5.org >>> %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s >> >> _______________________________________________ >> gem5-dev mailing list -- gem5-dev@gem5.org >> To unsubscribe send an email to gem5-dev-le...@gem5.org >> %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s > > _______________________________________________ > gem5-dev mailing list -- gem5-dev@gem5.org > To unsubscribe send an email to gem5-dev-le...@gem5.org > %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
_______________________________________________ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s