Re: sc_vector proposal

From: Andy Goodrich <acg@forteds.com>
Date: Wed Nov 10 2010 - 10:26:45 PST

sc_unnamed seems like a good change regardless if things trickle into the LRM or not. Also, I think it should go into the LRM.

Andy

On Nov 10, 2010, at 5:20 AM, john.aynsley@doulos.com wrote:

> Philipp, Andy,
>
> my_vec_of_modules2.init(N, sc_bind( &M::my_module_creator_func, this, sc_unamed::_1, sc_unamed::_2 ) );
>
> works.
>
>
> Do we need sc_unamed added to the LRM? Do we want to change it to sc_unnamed? Or to something else? Does anything else need adding from the revised boost stuff in SystemC?
>
> John A
>
>
>
> From: "Philipp A. Hartmann" <philipp.hartmann@offis.de>
> To: john.aynsley@doulos.com
> Cc: systemc-p1666-technical@eda.org
> Date: 09/11/2010 18:36
> Subject: Re: sc_vector proposal
>
>
>
>
> John,
>
> thanks for your comments and your nice review of the proposal.
> Please find my answers to your questions embedded below.
>
> On 09/11/10 14:06, john.aynsley@doulos.com wrote:
>
> [snip basic feature description]
>
> > Then we add a few wrinkles. It is possible to bind a vector-of-ports to a
> > vector-of-channels directly, with no explicit loop, e.g.
> >
> > module_inst->ports.bind( sigs ); // ports is a vector-of-ports
> > and sigs is a vector-of-sigs
> >
> > Very nice. It is also possible to bind just a subset of the
> > vector-of-ports, then come back for another pass later:
> >
> > typedef sc_vector<sc_inout<int> > port_type;
> > port_type::iterator it;
> >
> > // Bind upper half of ports vector to hi_sigs
> > it = module_inst->ports.bind( hi_sigs.begin(), hi_sigs.end() ); //
> > hi_sigs.size() < ports.size()
> >
> > // Bind lower half of ports vector to lo_sigs
> > it = module_inst->ports.bind( lo_sigs.begin(), lo_sigs.end(), it);
> > // Notice binding starts from position 'it' within ports vector
> >
> > The above syntax - having bind return the position of the 1st unbound
> > element - seems a little arcane to me. Are we all okay with it?
>
> Returning the "last" iterator follows the approach known from some of
> the iterator-based STL algorithms, like std::copy or std::transform.
> To me, this is the simplest way to define the interface. But I'm free
> to any suggestions in that area.
>
> Note, that the user can of course ignore the return value of the bind
> function and use an explicit iterator for the second bind offset:
>
> module_inst->ports.bind( lo_sigs.begin(), lo_sigs.end()
> , module_inst.begin() + hi_sigs.size() );
>
> If we feel, that this iterator-based interface is too complex to
> understand or describe, we can also drop it from the standard. Manually
> looping over parts of the vectors is still possible and maybe easier to
> explain:
>
> port_type it = module_inst.ports.begin();
>
> for( int i=0; i<hi_sigs.size(); ++i, ++it );
> it->bind( hi_sigs[i] );
>
> for( int i=0; i<lo_sigs.size(); ++i, ++it );
> it->bind( lo_sigs[i] );
>
> The returned iterator from the bind() calls can also be used to check,
> if all elements have been bound:
>
> sc_assert( it == module_inst->ports.end() ); // all bound
>
> > But sometimes, rather than having a vector-of-ports, you might have a
> > vector-of-modules each containing a single port. In this case it is
> > possible to treat these ports distributed across multiple modules as one
> > vector, using sc_view. For example:
> >
> > struct Initiator1: sc_module
> > {
> > sc_port<i_f> port;
> > ...
> > struct Target: public sc_module, private i_f
> > {
> > sc_export<i_f> xp;
> > ...
> >
> > sc_vector<Initiator1> initiator_vec;
> > sc_vector<Target> target_vec;
> >
> > sc_view(initiator_vec, &Initiator1::port).bind( sc_view
> > (target_vec, &Target::xp) );
> >
> > In the above
> > sc_view(initiator_vec, &Initiator1::port) creates a
> > vector-of-ports
> > sc_view(target_vec, &Target::xp) creates a vector-of-exports
> > .bind() does a vector-to-vector bind
> >
> > The semantics are very nice, but I am not particularly happy with the name
> > sc_view, because this is not suggestive of what is actually happening,
> > that is, gathering together a vector from a set of elements distributed
> > across another vector. Is there a precedent for the name sc_view, Phillip?
> > How about something like sc_gather or sc_make_vector or sc_vectorize
> > instead?
>
> I don't have a strong feeling about the name sc_view. Especially, since
> I'm not particularly talented in given well-descriptive names.
>
> The chosen name sc_view originates from the database world, where a
> view is some kind of a "stored query", which can then be manipulated
> more easily. See e.g. http://en.wikipedia.org/wiki/Database_view
>
> The cause is more or less the same here: With sc_view, you pre-select
> a given member of the vector, without actually creating a "real"
> sc_vector object. Only accesses via this "view" are forwarded to the
> _member object_ of the underlying vector element, instead of the element
> itself.
>
> I could think of other names like
> sc_member[_view]()
> sc_children()
> sc_select[ion]()
>
> But as I said, I'm not really good at this. ;-)
>
> [snip get_elements]
>
> > Finally, in the special case of a vector-of-modules, it is possible to
> > pass extra arguments to the module constructor, e.g.
> >
> > struct my_module: sc_module
> > {
> > my_module(sc_module_name n, string weird_arg ) {...}
> > ...
> > ...
> > sc_vector<my_module> my_vec;
> >
> > struct my_module_creator
> > {
> > my_module_creator( string arg ) : weird_arg(arg) {}
> >
> > my_module* operator() (const char* name, size_t)
> > {
> > return new my_module(name, weird_arg );
> > }
> > string weird_arg;
> > };
> > ...
> > my_vec.init(N, my_module_creator("The Creator"));
> >
> > This works, but creating the function object feels like having to jump
> > through hoops. I think regular users are going to find it confusing. Can
> > we do any clever tricks to make it easier to use?
>
> The reason for the complexity is two-fold:
>
> - The Creator needs to receive the designated name for the element
> (and, for convenience, the current index)
> - The Creator may need to have a local state e.g. to store
> or generate additional arguments.
>
> To use a custom Creator, the easiest/best solution depends on the
> current situation. If you have some globally accessible way to chose
> your additional arguments, you may get away with a plain function:
>
> my_module* my_module_creator_func( const char* name, size_t i )
> {
> return new my_module( name, WEIRD_ARG );
> }
> my_vec.init(N, my_module_creator_func );
>
> Another quite simple way is to define a local member function in the
> surrounding module and use sc_bind for the creator. This way, you can
> access the whole state of the owning module during creation and do all
> kinds of nice stuff, like binding transport functions etc:
>
> SC_MODULE(parent)
> {
> sc_vector< my_module > my_vec;
> std::string weird_arg;
>
> // member function as creator to use with sc_bind()
> my_module* init_element( const char* n, unsigned i )
> {
> my_module * mod = new my_module( n, weird_arg );
> mod->register_invalidate_direct_mem_ptr( this,
> &parent::invalidate_direct_mem_ptr, i );
> return mod;
> }
>
> SC_CTOR(parent)
> {
> // use sc_bind, "this" + placeholders as creator
> // note: you may need to use sc_unamed::_1 in SystemC 2.3
>
> my_vec.init( N, sc_bind( &parent::init_element, this, _1, _2 ) );
> }
> };
>
> To me, the above is as easy as it can get in current C++.
> Of course, C++0x lambdas will rock here in the future:
>
> std::string weird_arg;
> my_vec.init( N,
> [&]( const char*, size_t i)
> { return new my_module( n, weird_arg ); }
> );
>
> I'm of course interested in any simpler approach to custom element
> creation. But I've spent some time on this issue and could not come up
> with any easier solution for supporting arbitrary constructor signatures.
>
> I can see that this is not really part of C++/SystemC 101, but at
> least it's consistent with other functor APIs in C++, like Compare (in
> std::map and std::sort) or Function in std::for_each.
>
> Greetings from Oldenburg,
> Philipp
>
> --
> Philipp A. Hartmann
> Hardware/Software Design Methodology Group
>
> OFFIS Institute for Information Technology
> R&D Division Transportation · FuE-Bereich Verkehr
> Escherweg 2 · 26121 Oldenburg · Germany
> Phone/Fax: +49-441-9722-420/282 · PGP: 0x9161A5C0 · http://www.offis.de/
>
>
>

-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
Received on Wed Nov 10 10:27:23 2010

This archive was generated by hypermail 2.1.8 : Wed Nov 10 2010 - 10:27:25 PST