CnC
cnc.h
1 /* *******************************************************************************
2  * Copyright (c) 2007-2014, Intel Corporation
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * * Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of Intel Corporation nor the names of its contributors
13  * may be used to endorse or promote products derived from this software
14  * without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  ********************************************************************************/
27 
28 /*
29  Main include file for using CnC.
30  Provides all CnC classes except debug things.
31  See CnC::context for a very brief description on how to write a CnC program.
32 */
33 
34 #ifndef _CnC_H_ALREADY_INCLUDED_
35 #define _CnC_H_ALREADY_INCLUDED_
36 
37 #if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
38 // Workaround for overzealous compiler warnings
39 # pragma warning (push)
40 # pragma warning (disable: 4251 4275 4290)
41 #endif
42 
43 #include <cnc/internal/tag_collection_base.h>
44 #include <cnc/internal/item_collection_base.h>
45 #include <cnc/internal/context_base.h>
46 #include <cnc/internal/no_range.h>
47 
48 /// \brief CnC API
49 namespace CnC {
50 
51  typedef int error_type;
52 
53  // forward declarations
54  template< class T > class context;
55  struct debug;
56  template< typename Tag, typename Tuner > class tag_collection;
57  template< typename Tag, typename Item, typename Tuner > class item_collection;
58 
59  /// Steps return CNC_Success if execution was successful
60  const int CNC_Success = 0;
61  /// Steps return CNC_Failure if execution failed
62  const int CNC_Failure = 1;
63 
64  /// \brief A step collection is logical set of step instances.
65  ///
66  /// A step-collection must be prescribed by a tag-collection and it
67  /// can be part of consumer/producer relationships with item-collections.
68  /// Additionally, it can be the controller in control-dependencies (e.g. produce tags).
69  template< typename UserStep, typename Tuner = step_tuner<> >
70  class step_collection : public virtual Internal::traceable
71  {
72  public:
73  /// the type of the step as provided by the user
74  typedef UserStep step_type;
75  /// the type of the tuner as provided by the user
76  typedef Tuner tuner_type;
77 
78  /// \brief constructor which registers collection with given context
79  ///
80  /// \param ctxt the context this collection belongs to
81  /// \param name an optional name, used for debug output and tracing
82  /// \param userStep an optional user step argument, a copy will be created through copy-construction
83  /// \param tnr an optional tuner object which must persist throughout the lifetime of the step-collection
84  /// by default a default-constructed tuner will be used.
85  template< typename Derived >
86  step_collection( context< Derived > & ctxt, const std::string & name, const step_type & userStep, const tuner_type & tnr );
87  template< typename Derived >
89  template< typename Derived >
90  step_collection( context< Derived > & ctxt, const std::string & name );
91  template< typename Derived >
92  step_collection( context< Derived > & ctxt, const tuner_type & tnr, const std::string & name = std::string() );
93  template< typename Derived >
94  step_collection( context< Derived > & ctxt, const std::string & name, const step_type & userStep );
95 
96  ~step_collection();
97 
98  /// Declare this step-collecation as consumer of given item-collection
99  template< typename DataTag, typename Item, typename ITuner >
101 
102  /// Declare this step-collecation as producer for given item-collection
103  template< typename DataTag, typename Item, typename ITuner >
105 
106  /// Declare this step-collection as controller of given tag-collection
107  template< typename ControlTag, typename TTuner >
109 
110  private:
111  const step_type m_userStep;
112  const tuner_type & m_tuner;
113  Internal::distributable_context & m_context;
114  template< class Tag, class Step, class Arg, class TTuner, class STuner > friend class Internal::step_launcher;
115  };
116 
117  /// \brief A tag collection is a set of tags of the same type. It is
118  /// used to prescribe steps. By default, tags are not stored.
119  ///
120  /// Tag must provide copy and default constructors and the assigment
121  /// operator.
122  ///
123  /// If Tag is not convertable into size_t, a suitable hash_compare
124  /// class must be provided which satisifies the requirements for
125  /// tbb::concurrent_hash_map. The default cnc_tag_hash_compare works
126  /// for types that can be converted to size_t and have an
127  /// operator==. You can provide specialized templates for
128  /// cnc_hash and/or cnc_equal or cnc_tag_hash_compare
129  /// or specify and implement your own compatible class.
130  template< typename Tag, typename Tuner = tag_tuner<> >
131  class /*CNC_API*/ tag_collection
132  {
133  public:
134  /// the tag type
135  typedef Tag tag_type;
136 
137  /// \brief constructor which registers collection with given context
138  ///
139  /// \param ctxt the context this collection belongs to
140  /// \param name an optional name, used for debug output and tracing
141  /// \param tnr an optional tuner object which must persist throughout the lifetime of the tag-collection
142  /// by default a default-constructed tuner will be used.
143  template< class Derived >
144  tag_collection( context< Derived > & ctxt, const std::string & name, const Tuner & tnr );
145  template< class Derived >
146  tag_collection( context< Derived > & ctxt, const std::string & name = std::string() );
147  template< class Derived >
148  tag_collection( context< Derived > & ctxt, const Tuner & tnr );
149 
150  ~tag_collection();
151 
152  /// \brief Declare the prescription relationship between the tag collection
153  /// and a step collection.
154  ///
155  /// \param s class representing step collection. s is required to
156  /// provide the following const method, where Arg a is the optional
157  /// parameter described below.
158  ///
159  /// \code int execute( const Tag & tag, Arg & a ) const; \endcode
160  ///
161  /// A copy of s will be created by calling its copy constructor.
162  ///
163  /// \param arg This argument will be the parameter passed to
164  /// Step::execute and the tuner methods. The object must exist as
165  /// long as instances of the given step might be executed. Usually
166  /// arg will be the containing context.
167  ///
168  /// \return 0 if succeeded, error code otherwise
169  template< typename UserStep, typename STuner, typename Arg >
170  error_type prescribes( const step_collection< UserStep, STuner > & s, Arg & arg );
171 
172  /// \brief prescribe the associated step. If we are preserving tags for this collection, make a copy of the tag and store it in the collection.
173  /// \param t the tag to be put
174  void put( const Tag & t );
175 
176  /// \brief prescribe an entire range of tags
177  ///
178  /// \param r A range, which is potentially splittible through a partitioner.
179  /// Following the TBB range/splittable concept, extended by STL container requirements,
180  /// a range R must provide the following interface:
181  /// - R::R( const R& ) : Copy constructor.
182  /// - int size() : return number of elements (tags) in range
183  /// - const_iterator : forward iterator (operator++, operator tag_type() const)
184  /// to make it work with tbb::blocked_range, the cast operator is used instead of operator*().
185  /// - const_iterator begin() const : first member of range
186  /// - const_iterator end() const : Exclusive upper bound on range
187  /// Using it with the default_partitioner also requires
188  /// - R::R( R& r, tbb::split ) : Split r into two subranges.
189  /// - bool R::is_divisible() const : true if range can be partitioned into two subranges.
190  void put_range( const typename Tuner::range_type & r );
191  void put_range( const Internal::no_range & ) const;
192 
193  /// const forward iterator as in STL
194  typedef typename Tuner::tag_table_type::const_iterator const_iterator;
195 
196  /// \brief returns begin() as in STL containers
197  /// \note iteration through collections is not thread safe;
198  /// use it only between calls to CnC::context::wait() and putting tags
199  const_iterator begin() const;
200 
201  /// \brief returns end() as in STL containers
202  /// \note iteration through collections is not thread safe;
203  /// use it only between calls to CnC::context::wait() and putting tags
204  const_iterator end() const;
205 
206  /// \brief removes all of the tag instances from the collection
207  /// \note not thread-safe, to be called in safe state only
208  /// (between program start or calling context::wait() and putting the first tag or item).
209  void unsafe_reset();
210 
211  /// returns number of elements in collection
212  size_t size();
213 
214  /// returns true if size()==0, false otherwise
215  bool empty();
216 
217  /// callback type for tag-collections
218  /// \see register_callback
219  typedef typename Internal::tag_collection_base< Tag, Tuner >::callback_type callback_type;
220 
221  /// Call this to register a on-put-callback for the tag-collection.
222  /// When registered, callback.on_put( tag ) gets called when a tag was put successfully.
223  /// e.g. it will not get called a second time on a second put if memoization is enabled.
224  /// The call is blocking, e.g. the triggering/calling "put" will not return to its caller
225  /// until the callback has terminated.
226  /// The provided object will be deleted when the collection is deleted.
227  /// \see graph for more details, in particular about thread-safety issues
228  /// \note not thread-safe, to be called in safe state only
229  /// (between program start or calling context::wait() and putting the first tag or item).
230  /// \note not needed for regular CnC
231  void on_put( callback_type * cb );
232 
233  private:
234  Internal::tag_collection_base< Tag, Tuner > m_tagCollection;
235  //template< class T > friend class context;
236  friend struct ::CnC::debug;
237  };
238 
239  /// \brief An item collection is a mapping from tags to items.
240  ///
241  /// Tag and Item must provide copy and default constructors and the
242  /// assigment operator.
243  ///
244  /// Th last template argument is an optional tuner. The tuner provides
245  /// tuning hints, such as the type of the data store or information about
246  /// its use in distributed environments. Most importantly it tells the runtime
247  /// and compiler which type of data store it should use. By default that's
248  /// a hash-map (hashmap_tuner). For non default-supported tag types (e.g. those that are
249  /// not convertable into size_t) a suitable cnc_hash template
250  /// specialization must be provided. If in addition your type does not support std::equal_to
251  /// you also need to specialize cnc_equal.
252  /// For the vector-based data store (vector_tuner) that's not
253  /// necessary, but the tag-type must then be convertible to and from size_t.
254  /// \see CnC::item_tuner for more information.
255  ///
256  /// The CnC runtime will make a copy of your item when it is 'put' into
257  /// the item_collection. The CnC runtime will delete the copied item
258  /// copy once the get-count reaches 0 (or, if no get-count was
259  /// provided, once the collection is destroyed). If the item-type is a
260  /// pointer type, the runtime will not delete the memory the item
261  /// points to. If you store pointeres, you have to care for the appropriate
262  /// garbage collection, e.g. you might consider using smart pointers.
263  template< typename Tag, typename Item, typename Tuner = hashmap_tuner >
264  class /*CNC_API*/ item_collection
265  {
266  typedef Internal::item_collection_base< Tag, Item, Tuner > base_coll_type;
267  public:
268  /// the tag type
269  typedef Tag tag_type;
270  /// the data/item type
271  typedef Item data_type;
272 
273  /// const forward iterator as in STL
274  class const_iterator;
275 
276  /// \brief constructor which registers collection with given context
277  ///
278  /// \param ctxt the context this collection belongs to
279  /// \param name an optional name, used for debug output and tracing
280  /// \param tnr a tuner object which must persist throughout the lifetime of the step-collection
281  /// by default a default-constructed tuner will be used.
282  template< class Derived >
283  item_collection( context< Derived > & ctxt, const std::string & name, const Tuner & tnr );
284  template< class Derived >
285  item_collection( context< Derived > & ctxt, const std::string & name = std::string() );
286  template< class Derived >
287  item_collection( context< Derived > & ctxt, const Tuner & tnr );
288 
289  ~item_collection();
290 
291  /// \brief Declares the maxium tag value.
292  ///
293  /// Must be called prior to accessing the collection if the data store is a vector.
294  /// Useful only for dense tag-spaces.
295  /// \param mx the largest tag-value ever used for this collection
296  void set_max( size_t mx );
297 
298  /// \brief make copies of the item and the tag and store them in the collection.
299  /// \param tag the tag identifying the item
300  /// \param item the item to be copied and stored
301  void put( const Tag & tag, const Item & item );
302 
303  /// \brief get an item
304  /// \param tag the tag identifying the item
305  /// \param item reference to item to store result in
306  /// \throw DataNotReady throws exception if data not yet available.
307  void get( const Tag & tag, Item & item ) const;
308 
309  /// \brief try to get an item and store it in given object (non-blocking)
310  ///
311  /// \attention This method is unsafe: you can create non-deterministic results if you decide to
312  /// to perform semantically relevant actions if an item is unavailable (returns false)
313  ///
314  /// If the item is unavailable, it does not change item.
315  /// Make sure you call flush_gets() after last call to this method (of any item collection) within a step.
316  /// In any case, you must check the return value before accessing the item.
317  /// \param tag the tag identifying the item
318  /// \param item reference to item to store result in
319  /// \return true if item is available
320  /// \throw DataNotReady might throw exception if data not available (yet)
321  bool unsafe_get( const Tag & tag, Item & item ) const;
322 
323  /// \brief returns begin() as in STL containers
324  /// \note iteration through collections is not thread safe;
325  /// use it only between calls to CnC::context::wait() and putting tags
326  const_iterator begin() const;
327 
328  /// \brief returns end() as in STL containers
329  /// \note iteration through collections is not thread safe;
330  /// use it only between calls to CnC::context::wait() and putting tags
331  const_iterator end() const;
332 
333  /// \brief removes all of the item instances from the collection
334  /// \note not thread-safe, to be called in safe state only
335  /// (between program start or calling context::wait() and putting the first tag or item).
336  void unsafe_reset();
337 
338  /// returns number of elements in collection
339  size_t size();
340 
341  /// returns true if size()==0, false otherwise
342  bool empty();
343 
344  /// callback type for item-collections.
345  /// \see register_callback
346  typedef typename base_coll_type::callback_type callback_type;
347 
348  /// Call this to register a on-put-callback for the item-collection.
349  /// When registered, callback.on_put( tag, item ) gets called when an item was put successfully.
350  /// The call is blocking, e.g. the triggering/calling "put" will not return to its caller
351  /// until the callback has terminated.
352  ///
353  /// The provided object will be deleted when the collection is deleted.
354  ///
355  /// In distCnC, the callback will be executed on the (first) process returned
356  /// by tuner::consumed_on (which defaults to execution on the process which puts the item).
357  ///
358  /// \see graph for more details, in particular about thread-safety issues
359  /// \note not thread-safe, to be called in safe state only
360  /// (between program start or calling context::wait() and putting the first tag or item).
361  /// \note not needed for regular CnC
362  void on_put( callback_type * cb );
363 
364  private:
365  base_coll_type m_itemCollection;
366  friend struct ::CnC::debug;
367  friend class Internal::step_delayer;
368  friend class const_iterator;
369  };
370 
371 
372  /// \brief Base class for defining and using CnC (sub-)graphs.
373  ///
374  /// Derive from this class to define your own graph. It might
375  /// cooperate with other CnC graphs in the same context. A graph
376  /// can either be a normal CnC graph or anything else that uses
377  /// CnC collections as input and output.
378  ///
379  /// It is recommended to always use CnC types (e.g. collections)
380  /// to implement a graph. It facilitates implementation because
381  /// the CnC semantics allow automatically managing various tasks,
382  /// like distribution and termination detection.
383  ///
384  /// The fundamental communication channel between graphs and their
385  /// input/output collections are the normal get and put calls.
386  ///
387  /// The following paragraphs explain specifics needed to write
388  /// graphs which do not adhere to core CnC semantics. None of
389  /// this is needed for graphs that internally are "normal", fully
390  /// CnC compliant constructs.
391  ///
392  /// Besides get calls, tag- and item-collections also provide a
393  /// callback mechanism. Such callbacks can be registered for any
394  /// (input) collection individually (item_collection::on_put and
395  /// tag_collection::on_put). The registered callback will then be
396  /// called for every incoming item/tag after it was succesfully
397  /// put. The callback might (or might not) be called
398  /// asynchronously.
399  ///
400  /// \note multiple calls to the same or different callbacks might
401  /// be issued simultaneously. Hence your callbacks must
402  /// either have no side effects (other than through CnC) or
403  /// take care of adequate protection/synchronization
404  ///
405  /// \note If your graph executes anything outside of CnC steps or
406  /// outside callbacks (e.g. if spawns threads or alike), then
407  /// termination/quiescence handling needs to be addressed
408  /// explicitly (see graph::enter_quiescence and
409  /// graph::leave_quiescence). Graphs are born in
410  /// quiescent state!
411  ///
412  /// If you're using non-CnC data structures you will probably need
413  /// to explicitly take of distributed memory. A clone of the graph
414  /// gets instantiated on each process. You can send essages between
415  /// siblings through serializers which get instantiated through
416  /// graph::new_serializer. After marshalling the desired data
417  /// (CnC::serializer), the messages can be sent to individual
418  /// processes (graph::send_msg) or they may be broadcasted
419  /// (graph::bcast_msg). Messages can only be send from one
420  /// instance of a graph to its siblings on other processes.
421  /// Receiving messages is done by overwriting the graph::recv_msg
422  /// callback.
423  ///
424  /// Callbacks are executed on the first process of the list of
425  /// consumers/executing processes as provided by the collection's
426  /// tuner. If no consumer/executing process is provided /e.g. the default)
427  /// the callback is executed on the process where the item/tag is
428  /// produced.
429  class graph : public Internal::distributable
430  {
431  public:
432  /// \brief A graph requires a context and a name for its initialization.
433  ///
434  /// Do all your initialization/start-up stuff in the
435  /// constructor of your derived class. This implies that your
436  /// constructor needs to accept and wire all input-and
437  /// output-collections. The constructor must also call the
438  /// respective consumes/produces/prescribes calls. If your
439  /// graph operates/computes outside the steps and callbacks
440  /// you need to explicitly handle/manage quiescence (see
441  /// graph::enter_quiescence, graph::leave_quiescence).
442  template< typename Ctxt >
443  graph( CnC::context< Ctxt > & ctxt, const std::string & name = "" );
444 
445  virtual ~graph();
446 
447  /// \brief Tell the runtime that the graph reached (temporary) quiescence.
448  /// \note Entering quiescence means that it will not return to activity unless
449  /// new data arrives through a callback (to be registered with graph::register_callback).
450  /// \note Explicit quiescence handling is not needed if the graph operates/computes
451  /// only within the callbacks.
452  /// \note graphs are born in quiescent state. A call
453  /// to enter_quiescence must be paired with exactly one preceeding call to leave_quiescence
454  void enter_quiescence() const;
455 
456  /// \brief Tell the runtime that the graph leaves quiescence and goes back to activity.
457  /// Must be called only within a on_put callback (to be
458  /// registered through item_collection::on_put,
459  /// tag_collection::on_put) or within a CnC step. Leaving
460  /// quiescence outside a callback/step leads to undefined
461  /// behaviour (like dead-locks or worse).
462  /// \note Explicit quiescence handling is not needed if the
463  /// graph operates/computes only within the callbacks.
464  /// \note graphs are born in quiescent state.
465  void leave_quiescence() const;
466 
467  /// cleanup, e.g. collect garbage
468  virtual void cleanup();
469 
470  /// reset instance, e.g. remove entries from collection
471  /// \param dist if false, the current context is actually not distributed -> don't sync with remote siblings
472  virtual void unsafe_reset( bool dist );
473 
474  /// \brief Overwrite this if you need to exchange messages on distributed memory.
475  /// Each graph must implement its own "protocol" Sending
476  /// message is done through graph::new_serializer followed by
477  /// graph::send_msg / graph::bcast_msg.
478  /// \note not needed for regular CnC
479  virtual void recv_msg( serializer * );
480 
481  /// \brief Get a serializer
482  /// Caller must pass it to send/bcast or delete it.
483  /// Receiving messages is done in recv_msg callback.
484  /// \note not needed for regular CnC
485  serializer * new_serializer() const;
486 
487  /// \brief send a message (in serializer) to given recipient
488  /// Receiving messages is done in recv_msg callback.
489  /// \note not needed for regular CnC
490  void send_msg( serializer * ser, int rcver ) const;
491 
492  /// \brief broadcast message (in serializer) to all (other) ranks/processes
493  /// Receiving messages is done in recv_msg callback.
494  /// \note not needed for regular CnC
495  void bcast_msg( serializer * ser ) const;
496 
497  /// \brief broadcast message (in serializer) to given recipients
498  /// Receiving messages is done in recv_msg callback.
499  /// \note not needed for regular CnC
500  bool bcast_msg( serializer *ser , const int * rcvers, int nrecvrs ) const;
501 
502  /// \brief Flush a potentially hidden graph.
503  /// Usually is a nop.
504  /// Our reduction uses this to finalize all pending reductions.
505  /// (e.g. when the number of reduced items per reduction cannot be determined).
506  /// \note To be called in safe state only
507  /// (between program start or calling context::wait() and putting the first tag or item).
508  virtual void flush() {};
509 
510  private:
511  Internal::context_base & m_context;
512  };
513 
514  namespace Internal {
515  class distributor;
516  template< class T > class creator;
517  template< class Index, class Functor, class Tuner, typename Increment > class pfor_context;
518  }
519 
520  /**
521  \brief CnC context bringing together collections (for steps, items and tags).
522 
523  The user needs to derive his or her own context from the CnC::context.
524  The template argument to context is the user's context class itself.
525 
526  For example,
527  \code
528  struct my_context : public CnC::context< my_context >
529  {
530  CnC::step_collection< FindPrimes > steps;
531  CnC::tag_collection< int > oddNums;
532  CnC::item_collection< int,int > primes;
533  my_context()
534  : CnC::context< my_context >(),
535  steps( this ),
536  oddNums( this ),
537  primes( this )
538  {
539  oddNums.prescribes( steps );
540  }
541  };
542  \endcode
543 
544  Several contexts can be created and executed simultaneously.
545 
546  Execution starts as soon as a step(-instance) is prescribed through putting a tag.
547  All ready steps will be executed even if CnC::context::wait() is never be called.
548 
549  It is recommended to declare collections as members of a context derived from CnC::context.
550  This yields more maintanable code and future versions of CnC may require this convention.
551  **/
552  template< class Derived >
553  class /*CNC_API*/ context : protected Internal::context_base
554  {
555  public:
556  /// default constructor
557  context();
558  /// destructor
559  virtual ~context();
560 
561  /// \brief wait until all the steps prescribed by this context have completed execution.
562  /// \return 0 if succeeded, error code otherwise
563  error_type wait();
564 
565  /// \brief used with the preschedule tuner to finalize 'gets' in the pre-execution of a step
566  ///
567  /// Call this after last call to the non-blocking item_collection::unsafe_get method.
568  void flush_gets();
569 
570  /// reset all collections of this context
571  /// \note not thread-safe, to be called in safe state only
572  /// (between program start or calling context::wait() and putting the first tag or item).
573  void unsafe_reset();
574 
575  /// (distCnC) overload this if default construction on remote processes is not enough.
576  virtual void serialize( serializer & ){}
577 
578  private:
579  void init();
580  virtual void unsafe_reset( bool );
581  context( bool );
582  virtual int factory_id();
583  template< class Range, class Coll >
584  void divide_and_put( Range & range, int grain, Coll * coll, Internal::scheduler_i * sched );
585  friend struct ::CnC::debug;
586  friend class ::CnC::Internal::distributor;
587  friend class ::CnC::tuner_base;
588  friend class ::CnC::graph;
589  template< typename Tag, bool check_deps, typename Hasher, typename Equality > friend class ::CnC::cancel_tuner;
590  template< class T > friend class ::CnC::Internal::creator;
591  template< class Index, class Functor, class Tuner, typename Increment > friend class ::CnC::Internal::pfor_context;
592  template< typename Tag, typename Tuner > friend class tag_collection;
593  template< typename Step, typename Tuner > friend class step_collection;
594  template< typename Tag, typename Item, typename Tuner > friend class item_collection;
595  };
596 
597  /// \brief Execute f( i ) for every i in {first <= i=first+step*x < last and 0 <= x}.
598  ///
599  /// For different values of i, function execution might occur in parallel.
600  /// Returns functor object ocne all iterations have been executed.
601  /// Type Index must support operator+(increment) and operator-(Index), like C++ random access iterators do.
602  /// Executes on the local process only. No distribution to other processes supported.
603  /// \param first starting index of parallel iteration
604  /// \param last iteration stops before reaching last
605  /// \param incr increment index by this value in each iteration
606  /// \param f function to be executed
607  /// \param tuner defaults to pfor_tuner<>
608  template< class Index, class Functor, class Tuner, typename Increment >
609  void parallel_for( Index first, Index last, Increment incr, const Functor & f, const Tuner & tuner );
610  template< class Index, class Functor, typename Increment >
611  void parallel_for( Index first, Index last, Increment incr, const Functor & f );
612 
613 } // namespace cnc
614 
615 #include <cnc/internal/step_collection.h>
616 #include <cnc/internal/tag_collection.h>
617 #include <cnc/internal/item_collection.h>
618 #include <cnc/internal/graph.h>
619 #include <cnc/internal/context.h>
620 #include <cnc/internal/parallel_for.h>
621 #include <cnc/internal/hash_item_table.h>
622 #include <cnc/internal/vec_item_table.h>
623 
624 #if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
625 # pragma warning (pop)
626 # pragma warning( disable : 4355 )
627 #endif // warnings 4251 4275 4290 are back, 4355 is hidden
628 
629 #endif // _CnC_H_ALREADY_INCLUDED_
Debugging interface providing tracing and timing capabilities.
Definition: debug.h:56
step_collection(context< Derived > &ctxt, const std::string &name, const step_type &userStep, const tuner_type &tnr)
constructor which registers collection with given context
void parallel_for(Index first, Index last, Increment incr, const Functor &f, const Tuner &tuner)
Execute f( i ) for every i in {first <= i=first+step*x < last and 0 <= x}.
void controls(CnC::tag_collection< ControlTag, TTuner > &)
Declare this step-collection as controller of given tag-collection.
Tuner::tag_table_type::const_iterator const_iterator
const forward iterator as in STL
Definition: cnc.h:194
CnC API.
Definition: cnc.h:49
Tuner tuner_type
the type of the tuner as provided by the user
Definition: cnc.h:76
A tag collection is a set of tags of the same type. It is used to prescribe steps. By default, tags are not stored.
Definition: cnc.h:56
Internal::tag_collection_base< Tag, Tuner >::callback_type callback_type
Definition: cnc.h:219
virtual void serialize(serializer &)
(distCnC) overload this if default construction on remote processes is not enough.
Definition: cnc.h:576
UserStep step_type
the type of the step as provided by the user
Definition: cnc.h:74
base_coll_type::callback_type callback_type
Definition: cnc.h:346
Base class for defining and using CnC (sub-)graphs.
Definition: cnc.h:429
CnC context bringing together collections (for steps, items and tags).
Definition: cnc.h:54
A step collection is logical set of step instances.
Definition: cnc.h:70
const int CNC_Failure
Steps return CNC_Failure if execution failed.
Definition: cnc.h:62
Item data_type
the data/item type
Definition: cnc.h:271
virtual void flush()
Flush a potentially hidden graph. Usually is a nop. Our reduction uses this to finalize all pending r...
Definition: cnc.h:508
Handles serilialization of data-objects.
Definition: serializer.h:348
void produces(CnC::item_collection< DataTag, Item, ITuner > &)
Declare this step-collecation as producer for given item-collection.
Tag tag_type
the tag type
Definition: cnc.h:269
An item collection is a mapping from tags to items.
Definition: cnc.h:57
const int CNC_Success
Steps return CNC_Success if execution was successful.
Definition: cnc.h:60
void consumes(CnC::item_collection< DataTag, Item, ITuner > &)
Declare this step-collecation as consumer of given item-collection.
Tag tag_type
the tag type
Definition: cnc.h:135