From 1da026a49734de452fcd83302e84e0f00ea7e5fd Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Thu, 4 Jul 2013 03:03:32 +0000 Subject: [PATCH] I can't believe it still isn't working. It was working just fine on the laptop, but all sorts of tests are failing again. So obnoxious!!! git-svn-id: https://svn.dealii.org/trunk@29936 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/include/deal.II/base/work_stream.h | 87 ++++++---------------- 1 file changed, 24 insertions(+), 63 deletions(-) diff --git a/deal.II/include/deal.II/base/work_stream.h b/deal.II/include/deal.II/base/work_stream.h index 6a8749bb58..3a98da2afa 100644 --- a/deal.II/include/deal.II/base/work_stream.h +++ b/deal.II/include/deal.II/base/work_stream.h @@ -19,7 +19,6 @@ #include #include #include -#include #ifdef DEAL_II_WITH_THREADS # include @@ -28,7 +27,6 @@ #include #include -#include DEAL_II_NAMESPACE_OPEN @@ -155,16 +153,11 @@ namespace WorkStream * on. This last argument is an integer * between one and chunk_size. The * arrays have a length of chunk_size. - * - * The pointer stored by the thread local object must - * be so that it's deleted on all threads when the thread - * local object is destroyed. Thus, use auto_ptr. */ typedef std_cxx1x::tuple, - Threads::ThreadLocalStorage >*, - const ScratchData *, - std::vector, + ScratchData *, + std::vector, unsigned int> ItemType; @@ -187,7 +180,6 @@ namespace WorkStream tbb::filter (/*is_serial=*/true), remaining_iterator_range (begin, end), ring_buffer (buffer_size), - sample_scratch_data (sample_scratch_data), n_emitted_items (0), chunk_size (chunk_size) { @@ -202,10 +194,20 @@ namespace WorkStream tasks += Threads::new_task (&IteratorRangeToItemStream::init_buffer_elements, *this, i, + std_cxx1x::cref(sample_scratch_data), std_cxx1x::cref(sample_copy_data)); tasks.join_all (); } + /** + * Destructor. + */ + ~IteratorRangeToItemStream () + { + for (unsigned int i=0; i(ring_buffer[i]); + } + /** * Create a item and return a * pointer to it. @@ -220,20 +222,20 @@ namespace WorkStream // initialize the next item. it may // consist of at most chunk_size // elements - std_cxx1x::get<4>(*current_item) = 0; + std_cxx1x::get<3>(*current_item) = 0; while ((remaining_iterator_range.first != remaining_iterator_range.second) && - (std_cxx1x::get<4>(*current_item) < chunk_size)) + (std_cxx1x::get<3>(*current_item) < chunk_size)) { - std_cxx1x::get<0>(*current_item)[std_cxx1x::get<4>(*current_item)] + std_cxx1x::get<0>(*current_item)[std_cxx1x::get<3>(*current_item)] = remaining_iterator_range.first; ++remaining_iterator_range.first; - ++std_cxx1x::get<4>(*current_item); + ++std_cxx1x::get<3>(*current_item); } - if (std_cxx1x::get<4>(*current_item) == 0) + if (std_cxx1x::get<3>(*current_item) == 0) // there were no items // left. terminate the pipeline return 0; @@ -257,32 +259,6 @@ namespace WorkStream */ std::vector ring_buffer; - /** - * Scratch data object. Each thread will - * have its own local copy of the scratch object. However, since - * some operations on the *elements* of the scratch object may - * be in parallel (e.g., setting a vector of the scratch object - * may also be parallelized (something we have no control over - * from WorkStream, we need to pay attention that the scratch - * object itself exists once per thread but the elements of the - * scratch object are not thread-local themselves -- in other - * words, the scratch object exists once per thread, but - * lives in global memory space rather than thread-local memory - * space. - * - * The pointer stored by the thread local object must - * be so that it's deleted on all threads when the thread - * local object is destroyed. Thus, use auto_ptr. - */ - Threads::ThreadLocalStorage > thread_local_scratch; - - /** - * A reference to a sample scratch data that will be used to - * initialize the thread-local pointers to a scratch data object - * each of the worker tasks uses. - */ - const ScratchData &sample_scratch_data; - /** * Counter for the number of emitted * items. Each item may consist of up @@ -310,6 +286,7 @@ namespace WorkStream * the ring buffer. */ void init_buffer_elements (const unsigned int element, + const ScratchData &sample_scratch_data, const CopyData &sample_copy_data) { Assert (std_cxx1x::get<1>(ring_buffer[element]) == 0, @@ -318,10 +295,8 @@ namespace WorkStream std_cxx1x::get<0>(ring_buffer[element]) .resize (chunk_size, remaining_iterator_range.second); std_cxx1x::get<1>(ring_buffer[element]) - = &thread_local_scratch; + = new ScratchData(sample_scratch_data); std_cxx1x::get<2>(ring_buffer[element]) - = &sample_scratch_data; - std_cxx1x::get<3>(ring_buffer[element]) .resize (chunk_size, sample_copy_data); } }; @@ -370,31 +345,17 @@ namespace WorkStream ItemType *current_item = static_cast (item); - Threads::ThreadLocalStorage > * - thread_local_scratch_pointer = std_cxx1x::get<1>(*current_item); - - std::auto_ptr &scratch_pointer - = thread_local_scratch_pointer->get(); - - // see if this is the first time we encounter - // the current scratch object (which is thread-local). - // if so, initialize the pointer - if (!scratch_pointer.get()) - scratch_pointer.reset - (new ScratchData(*std_cxx1x::get<2>(*current_item))); - - // then call the worker function on each element of the chunk we were // given. since these worker functions are called on separate threads, // nothing good can happen if they throw an exception and we are best // off catching it and showing an error message - for (unsigned int i=0; i(*current_item); ++i) + for (unsigned int i=0; i(*current_item); ++i) { try { worker (std_cxx1x::get<0>(*current_item)[i], - *scratch_pointer.get(), - std_cxx1x::get<3>(*current_item)[i]); + *std_cxx1x::get<1>(*current_item), + std_cxx1x::get<2>(*current_item)[i]); } catch (const std::exception &exc) { @@ -472,11 +433,11 @@ namespace WorkStream // initiate copying data. for the same reasons as in the worker class // above, catch exceptions rather than letting it propagate into // unknown territories - for (unsigned int i=0; i(*current_item); ++i) + for (unsigned int i=0; i(*current_item); ++i) { try { - copier (std_cxx1x::get<3>(*current_item)[i]); + copier (std_cxx1x::get<2>(*current_item)[i]); } catch (const std::exception &exc) { -- 2.39.5