コード例 #1
0
ファイル: blackscholes.m4.cpp プロジェクト: artintal/goa2
  void operator()(const tbb::blocked_range<int> &range) const {
    fptype price;
    int begin = range.begin();
    int end = range.end();

    for (int i=begin; i!=end; i++) {
      /* Calling main function to calculate option value based on 
       * Black & Scholes's equation.
       */

      price = BlkSchlsEqEuroNoDiv( sptprice[i], strike[i],
                                   rate[i], volatility[i], otime[i], 
                                   otype[i], 0);
      prices[i] = price;

#ifdef ERR_CHK 
      fptype priceDelta = data[i].DGrefval - price;
      if( fabs(priceDelta) >= 1e-5 ){
        fprintf(stderr,"Error on %d. Computed=%.5f, Ref=%.5f, Delta=%.5f\n",
               i, price, data[i].DGrefval, priceDelta);
        numError ++;
      }
#endif
    }
  }
コード例 #2
0
    void operator () (const tbb::blocked_range<int> &range) const {
        for(int i=range.begin(); i<range.end(); i++) {
            list_node *node;
            if (addok(head, i, column)) {
                // add the node

#ifdef QUIT_ON_SOLUTION // QUIT as soon as a solution is found
                if (node!=NULL && solution == NULL) {
#endif
                    list_node new_node;
                    new_node.next = head;
                    new_node.row  = i;
                    if (column+1<SIZE) {
#ifdef CUTOFF
                        if (column+1>=CUTOFF_LEVEL)
                            ser_nqueens_rec(column+1, &new_node);
                        else
                            nqueens_rec(column+1, &new_node);
#else
                        nqueens_rec(column+1, &new_node);
#endif

                    } else { // found a solution 
                        //solution = &new_node;
                        solution_count++; //atomic
                        //abort()
                    }
#ifdef QUIT_ON_SOLUTION // QUIT as soon as a solution is found
                }
#endif
            } // end if addok
        // else do nothing -- dead computation branch
        }
    }
コード例 #3
0
ファイル: test_combinable.cpp プロジェクト: xiangyuan/Unreal4
    void operator()( const tbb::blocked_range<int> &r ) const {
        T one = 1;

        for (int i = r.begin(); i < r.end(); ++i) {
            locals.local().push_back( one );
        }
    }
コード例 #4
0
ファイル: colorx_node.cpp プロジェクト: JohanAberg/Ramen
void colorx_node_t::do_expression( const tbb::blocked_range<int>& range, const Imath::Box2i& area, const render::context_t& context)
{
	std::string color_expr = get_value<std::string>( param( expr_param_name()));
	image_expression_t expr( color_expr, this, color_context);
	RAMEN_ASSERT( expr.isValid());

	expr.setup_variables( this, context);
	image::const_image_view_t src = input_as<image_node_t>()->const_subimage_view( area);
	image::image_view_t dst = subimage_view( area);
	
	SeVec3d& cvar = expr.vec_vars["Cs"].val;
	double& avar = expr.vars["As"].val;
	double *out_avar = expr.get_local_var_ref( "Ao", &avar);

	for( int y = range.begin(); y < range.end(); ++y)
	{
		image::const_image_view_t::x_iterator src_it( src.row_begin( y));
		image::image_view_t::x_iterator dst_it( dst.row_begin( y));

		for( int x = 0, xe = src.width(); x < xe; ++x)
		{
			cvar[0] = boost::gil::get_color( *src_it, boost::gil::red_t());
			cvar[1] = boost::gil::get_color( *src_it, boost::gil::green_t());
			cvar[2] = boost::gil::get_color( *src_it, boost::gil::blue_t());
			avar = boost::gil::get_color( *src_it, boost::gil::alpha_t());

			SeVec3d result = expr.evaluate();
			*dst_it++ = image::pixel_t( result[0], result[1], result[2], *out_avar);
			++src_it;
		}
	}
}
コード例 #5
0
  void operator()(const tbb::blocked_range<int>& range) const {
    GraphType::SrcSeedList seed_remove_list[2];

    /* compute cuts for each seed using the precomputation graph */
    for (int fg_idx = range.begin(); fg_idx != range.end(); ++fg_idx) {
      // copy the precomputation graph
      GraphType* g_fg_precomp = new GraphType(*g_precomp);
      (*g_fgs_precomp)[fg_idx] = g_fg_precomp;

      // get the fg seeds sans the current seed
      generate_seed_fix_list(seed_remove_list, *fg_nodes, fg_idx);
      // transform all S trees (sans the current seed) to sink
      g_fg_precomp->transform_seed_trees(fg_idx, seed_remove_list);

      g_fg_precomp->check_tree_integrity();

      // generate visualization after the seed tree transformation
      g_fg_precomp->generate_graph_visualization(
          node_rows, ((boost::format("graph1_%d") % (fg_idx + 1)).str()));

      // compute the cut after the precomputation for this seed
      int flow_fg_precomp = run_print_maxflow(g_fg_precomp, *fg_nodes,
                                              node_rows, true);

      // generate visualization after cut computation (and generate final pdf)
      g_fg_precomp->generate_graph_visualization(
          node_rows, ((boost::format("graph2_%d") % (fg_idx + 1)).str()));
      g_fg_precomp->generate_pdf_graphs(
          (boost::format("fg%d_precomp") % (fg_idx + 1)).str());
    }
  }
コード例 #6
0
ファイル: test_mutex.cpp プロジェクト: artog/Raytracer
 /** Increments counter once for each iteration in the iteration space. */
 void operator()( tbb::blocked_range<size_t>& range ) const {
     for( size_t i=range.begin(); i!=range.end(); ++i ) {
         //! Every 8th access is a write access
         const bool write = (i%8)==7;
         bool okay = true;
         bool lock_kept = true;
         if( (i/8)&1 ) {
             // Try implicit acquire and explicit release
             typename I::mutex_type::scoped_lock lock(invariant.mutex,write);
             execute_aux(lock, i, write, /*ref*/okay, /*ref*/lock_kept);
             lock.release();
         } else {
             // Try explicit acquire and implicit release
             typename I::mutex_type::scoped_lock lock;
             lock.acquire(invariant.mutex,write);
             execute_aux(lock, i, write, /*ref*/okay, /*ref*/lock_kept);
         }
         if( !okay ) {
             REPORT( "ERROR for %s at %ld: %s %s %s %s\n",invariant.mutex_name, long(i),
                     write     ? "write,"                  : "read,",
                     write     ? (i%16==7?"downgrade,":"") : (i%8==3?"upgrade,":""),
                     lock_kept ? "lock kept,"              : "lock not kept,", // TODO: only if downgrade/upgrade
                     (i/8)&1   ? "impl/expl"               : "expl/impl" );
         }
     }
 }
	void operator()(const tbb::blocked_range<int>& r) const
	{
		int begin = r.begin(),
			end = r.end();

		double dmax;
		
		//
		// Define precision(epsilon value)
		double e = .001;
		
		do
		{
			dmax = .0;
			for(int i = begin; i != end; ++i){
				for (int j = 1; j < N; ++j){
					temp_matrix[i][j] = 0.25*(tmatrix[i][j - 1] + tmatrix[i][j + 1] + tmatrix[i - 1][j] + tmatrix[i + 1][j]);
					double diff = fabs(temp_matrix[i][j] - tmatrix[i][j]);
					if (dmax < diff)
						dmax = diff;
					
					tmatrix[i][j] = temp_matrix[i][j];
				}
			}
		} while (dmax > e);
	}
コード例 #8
0
ファイル: normal_3d_tbb.hpp プロジェクト: jonaswitt/nestk
template <typename PointInT, typename PointOutT> void
pcl::TBB_NormalEstimationTBB<PointInT, PointOutT>::operator () (const tbb::blocked_range <size_t> &r) const
{
  float vpx, vpy, vpz;
  feature_->getViewPoint (vpx, vpy, vpz);
  // Iterating over the entire index vector
  for (size_t idx = r.begin (); idx != r.end (); ++idx)
  {
    std::vector<int> nn_indices (feature_->getKSearch ());
    std::vector<float> nn_dists (feature_->getKSearch ());

    feature_->searchForNeighbors ((*feature_->getIndices ())[idx], feature_->getSearchParameter (), nn_indices, nn_dists);

    // 16-bytes aligned placeholder for the XYZ centroid of a surface patch
    Eigen::Vector4f xyz_centroid;
    // Estimate the XYZ centroid
    compute3DCentroid (*feature_->getSearchSurface (), nn_indices, xyz_centroid);

    // Placeholder for the 3x3 covariance matrix at each surface patch
    EIGEN_ALIGN16 Eigen::Matrix3f covariance_matrix;
    // Compute the 3x3 covariance matrix
    computeCovarianceMatrix (*feature_->getSearchSurface (), nn_indices, xyz_centroid, covariance_matrix);

    // Get the plane normal and surface curvature
    solvePlaneParameters (covariance_matrix,
                          output_.points[idx].normal[0], output_.points[idx].normal[1], output_.points[idx].normal[2], output_.points[idx].curvature);

    flipNormalTowardsViewpoint<PointInT> (feature_->getSearchSurface ()->points[idx], vpx, vpy, vpz,
                                          output_.points[idx].normal[0], output_.points[idx].normal[1], output_.points[idx].normal[2]);
  }
}
コード例 #9
0
ファイル: bfs.cpp プロジェクト: atzannes/TBBBenchmarks
    void operator () (const tbb::blocked_range<int> &range) const {
        int i; 
        PARTITIONER partitioner;
        for (i=range.begin(); i<range.end(); i++) {
            //printf("Outer Loop Body[%d<=%d<%d]=[0,%d]\n", range.begin(), i, range.end(), degrees[currentLevelSet[i]]);
#ifdef SEQUENTIAL_INNER
            for(int j=0; j<degrees[currentLevelSet[i]]; j++) {
                int oldGatek;
                int freshNode,currentEdge;

                currentEdge = vertices[currentLevelSet[i]]+j;
                // let's handle one edge
#ifdef XBOFILE
                freshNode = edges[currentEdge][1]; // 0 RTM, value was prefetched
#else
                freshNode = edges[currentEdge];    // 0 RTM, value was prefetched
#endif
                oldGatek = -1;
                // test gatekeeper 
                oldGatek = gatekeeper[freshNode].fetch_and_increment();
                if (oldGatek == 0) { // destination vertex unvisited!
                    // increment newLevelIndex atomically
                    int myIndex = newLevelIndex.fetch_and_increment();
                    // store fresh node in new level
                    newLevelSet[myIndex] = freshNode;
 
                    level[freshNode] = currentLevel + 1;
                } // end if freshNode
            }
#else
            tbb::parallel_for (tbb::blocked_range<int>(0,degrees[currentLevelSet[i]],INNER_GRAINSIZE), innerLoopBody(i), partitioner);
#endif
        }
    }
コード例 #10
0
ファイル: bfs.cpp プロジェクト: atzannes/TBBBenchmarks
    void operator () (const tbb::blocked_range<int> &range) const {
        int j;
        for(j=range.begin(); j<range.end(); j++) {
            //printf("Inner Loop Body (x,y)=(%d,%d) where y in [%d,%d)\n", i,j,range.begin(), range.end() );
	    int oldGatek;
            int freshNode,currentEdge;

            currentEdge = vertices[currentLevelSet[i]]+j;
            // let's handle one edge
#ifdef XBOFILE
            freshNode = edges[currentEdge][1]; // 0 RTM, value was prefetched
#else
            freshNode = edges[currentEdge];    // 0 RTM, value was prefetched
#endif
            oldGatek = -1;
            // test gatekeeper 
            oldGatek = gatekeeper[freshNode].fetch_and_increment();
	    if (oldGatek == 0) { // destination vertex unvisited!
                // increment newLevelIndex atomically
                int myIndex = newLevelIndex.fetch_and_increment();
	        // store fresh node in new level
	        newLevelSet[myIndex] = freshNode;

	        level[freshNode] = currentLevel + 1;
	    } // end if freshNode
        } // end for j
    }
コード例 #11
0
MSC_NAMESPACE_BEGIN

void RayBoundingbox::operator()(const tbb::blocked_range< size_t >& r)
{
  size_t begin = r.begin();
  size_t end = r.end();

  m_value.min[0] = m_data[begin].org[0];
  m_value.min[1] = m_data[begin].org[1];
  m_value.min[2] = m_data[begin].org[2];
  m_value.max[0] = m_data[begin].org[0];
  m_value.max[1] = m_data[begin].org[1];
  m_value.max[2] = m_data[begin].org[2];

  for(size_t index = begin; index < end; ++index)
  {
    if(m_data[index].org[0] < m_value.min[0])
      m_value.min[0] = m_data[index].org[0];
    if(m_data[index].org[1] < m_value.min[1])
      m_value.min[1] = m_data[index].org[1];
    if(m_data[index].org[2] < m_value.min[2])
      m_value.min[2] = m_data[index].org[2];

    if(m_data[index].org[0] > m_value.max[0])
      m_value.max[0] = m_data[index].org[0];
    if(m_data[index].org[1] > m_value.max[1])
      m_value.max[1] = m_data[index].org[1];
    if(m_data[index].org[2] > m_value.max[2])
      m_value.max[2] = m_data[index].org[2];
  }
}
コード例 #12
0
ファイル: tbbKernel.cpp プロジェクト: AiYong/OpenSubdiv
    void operator() (tbb::blocked_range<int> const &r) const {
#define USE_SIMD
#ifdef USE_SIMD
        if (_srcDesc.length==4 and _srcDesc.stride==4 and _dstDesc.stride==4) {

            // SIMD fast path for aligned primvar data (4 floats)
            int offset = _offsets[r.begin()];
            ComputeStencilKernel<4>(_vertexSrc, _vertexDst,
                _sizes, _indices+offset, _weights+offset, r.begin(), r.end());

        } else if (_srcDesc.length==8 and _srcDesc.stride==4 and _dstDesc.stride==4) {

            // SIMD fast path for aligned primvar data (8 floats)
            int offset = _offsets[r.begin()];
            ComputeStencilKernel<8>(_vertexSrc, _vertexDst,
                _sizes, _indices+offset, _weights+offset, r.begin(), r.end());

        } else {
#else
        {
#endif
            int const * sizes = _sizes;
            int const * indices = _indices;
            float const * weights = _weights;

            if (r.begin()>0) {
                sizes += r.begin();
                indices += _offsets[r.begin()];
                weights += _offsets[r.begin()];
            }

            // Slow path for non-aligned data
            float * result = (float*)alloca(_srcDesc.length * sizeof(float));

            for (int i=r.begin(); i<r.end(); ++i, ++sizes) {

                clear(result, _dstDesc);

                for (int j=0; j<*sizes; ++j) {
                    addWithWeight(result, _vertexSrc, *indices++, *weights++, _srcDesc);
                }

                copy(_vertexDst, i, result, _dstDesc);
            }
        }
    }
};
コード例 #13
0
ファイル: tbbKernel.cpp プロジェクト: AiYong/OpenSubdiv
    void computeWithDerivative(tbb::blocked_range<int> const &r) const {
        float wP[20], wDs[20], wDt[20];
        BufferAdapter<const float> srcT(_src + _srcDesc.offset,
                                        _srcDesc.length,
                                        _srcDesc.stride);
        BufferAdapter<float> dstT(_dst + _dstDesc.offset
                                       + r.begin() * _dstDesc.stride,
                                  _dstDesc.length,
                                  _dstDesc.stride);
        BufferAdapter<float> dstDuT(_dstDu + _dstDuDesc.offset
                                       + r.begin() * _dstDuDesc.stride,
                                  _dstDuDesc.length,
                                  _dstDuDesc.stride);
        BufferAdapter<float> dstDvT(_dstDv + _dstDvDesc.offset
                                       + r.begin() * _dstDvDesc.stride,
                                  _dstDvDesc.length,
                                  _dstDvDesc.stride);

        for (int i = r.begin(); i < r.end(); ++i) {
            PatchCoord const &coord = _patchCoords[i];
            PatchArray const &array = _patchArrayBuffer[coord.handle.arrayIndex];

            int patchType = array.GetPatchType();
            Far::PatchParam const & param =
                _patchParamBuffer[coord.handle.patchIndex];

            int numControlVertices = 0;
            if (patchType == Far::PatchDescriptor::REGULAR) {
                Far::internal::GetBSplineWeights(param,
                                                 coord.s, coord.t, wP, wDs, wDt);
                numControlVertices = 16;
            } else if (patchType == Far::PatchDescriptor::GREGORY_BASIS) {
                Far::internal::GetGregoryWeights(param,
                                                 coord.s, coord.t, wP, wDs, wDt);
                numControlVertices = 20;
            } else if (patchType == Far::PatchDescriptor::QUADS) {
                Far::internal::GetBilinearWeights(param,
                                                  coord.s, coord.t, wP, wDs, wDt);
                numControlVertices = 4;
            } else {
                assert(0);
            }

            const int *cvs =
                &_patchIndexBuffer[array.indexBase + coord.handle.vertIndex];

            dstT.Clear();
            dstDuT.Clear();
            dstDvT.Clear();
            for (int j = 0; j < numControlVertices; ++j) {
                dstT.AddWithWeight(srcT[cvs[j]], wP[j]);
                dstDuT.AddWithWeight(srcT[cvs[j]], wDs[j]);
                dstDvT.AddWithWeight(srcT[cvs[j]], wDt[j]);
            }
            ++dstT;
            ++dstDuT;
            ++dstDvT;
        }
    }
コード例 #14
0
ファイル: icontask.cpp プロジェクト: ajaskier/gerbil
	void operator()(const tbb::blocked_range<short>& range) const {
		for (short labelid=range.begin(); labelid!=range.end(); ++labelid) {
			// Compute mask.
			// For big images it might make sense to parallelize this on a
			// smaller granularity (pixel ranges).
			// And it might be a good idea to cache these.
			cv::Mat1b mask(labels == labelid);

			if(tbb::task::self().is_cancelled()) {
				//GGDBGM("aborted through tbb cancel." << endl);
				return;
			}

			// transform mask into icon
			cv::Mat1b masktrf = cv::Mat1b::zeros(iconSizecv);
			cv::warpAffine(mask, masktrf, trafo, iconSizecv, CV_INTER_AREA);

			if(tbb::task::self().is_cancelled()) {
				//GGDBGM("aborted through tbb cancel." << endl);
				return;
			}
			// The rest is probably too fast to allow checking for cancellation.

			QColor color = ctx.colors.at(labelid);

			// Fill icon with solid color in ARGB format.
			cv::Vec4b argb(0, color.red(), color.green(), color.blue());
			cv::Mat4b icon = cv::Mat4b(iconSizecv.height,
									   iconSizecv.width,
									   argb);

			// Now apply alpha channel.
			// Note: this is better than OpenCV's mask functionality as it
			// preserves the antialiasing!

			// Make ARGB 'array' which is interleaved to a true ARGB image
			// using mixChannels.
			const cv::Mat1b zero = cv::Mat1b::zeros(iconSizecv.height,
													iconSizecv.width);
			const cv::Mat in[] = {masktrf, zero, zero, zero};
			// Copy only the alpha channel (0) of the in array into the
			// alpha channel (0) of the ARGB icon.
			const int mix[] = {0,0};
			// 4 input matrices, 1 dest, 1 mix-pair
			cv::mixChannels(in,4, &icon,1, mix,1);
			// convert the result to a QImage
			QImage qimage = Mat2QImage(icon);

			/* draw a border (alternative: the icon view could do this) */
			QPainter p(&qimage);
			QPen pen(color);
			// ensure border visibility, fixed to 1px
			pen.setWidthF(1.f);
			p.setPen(pen);
			p.drawRect(brect);

			ctx.icons[labelid] = qimage;
		}
	}
コード例 #15
0
ファイル: test_concurrent_monitor.cpp プロジェクト: adiog/tbb
 /** Increments counter once for each iteration in the iteration space. */
 void operator()( tbb::blocked_range<size_t>& range ) const {
     for( size_t i=range.begin(); i!=range.end(); ++i ) {
         typename C::mutex_type::ScopedLock lock(counter.mutex, i);
         counter.value = counter.value+1;
         if( D>0 )
             for( int j=0; j<D; ++j ) __TBB_Yield();
     }
 }
コード例 #16
0
    void operator()( const tbb::blocked_range<int> &r ) const {
        T one;
        test_helper<T>::set(one, 1);

        for (int i = r.begin(); i < r.end(); ++i) {
            locals.local().push_back( one );
        }
    }
コード例 #17
0
        void operator()(const tbb::blocked_range<uint64_t>&   range) const {

            for(uint64_t count_strhex = range.begin();
                    count_strhex != range.end();
                    ++count_strhex) {
                binary_hex_.push_back(str_hex_[count_strhex]);
            }// for
        }// operator ()
コード例 #18
0
ファイル: koumes21.cpp プロジェクト: brtzsnr/sorting
 void operator() (tbb::blocked_range<int>& range) const {
     for (int i = range.begin(); i < range.end(); ++i) {
         double* begin = &data[offsets[i]];
         double* end = &data[offsets[i+1]];
         //std::sort(begin, end);
         radixSort(begin, end-begin);
     }
 }
コード例 #19
0
ファイル: ppsum.cpp プロジェクト: rheiland/rheiland.github.io
  void operator() (const tbb::blocked_range<int>& range) const {
//    float *v = my_v;
    sum = 0.0;
    for (int i=range.begin(); i!=range.end(); ++i) {
      sum += *vp;
      vp++;
    }
  }
コード例 #20
0
 // Execute the sort as specified.
 void operator()(const tbb::blocked_range<size_t> &range) const {
   for (size_t wi = range.begin(); wi < range.end(); ++wi) {
     m_WS->getSpectrum(wi).sort(m_sortType);
   }
   // Report progress
   if (prog)
     prog->report("Sorting");
 }
コード例 #21
0
 void operator () (tbb::blocked_range<int> &rng) {
   typename WDPin::ReductionType tmpi;
   const int end = rng.end ();
   for (int i = rng.begin (); i != end; ++i) {
     tmpi = wd.generate (i);
     result = wd.reduce (result, tmpi);
   }
 }
コード例 #22
0
 void operator()( const tbb::blocked_range<int> &r ) const {
     for (int i = r.begin(); i != r.end(); ++i) {
         bool was_there;
         T& my_local = sums.local(was_there);
         if(!was_there) my_local = 0;
          my_local +=  1 ;
     }
 }
コード例 #23
0
MSC_NAMESPACE_BEGIN

void RayIntersect::operator()(const tbb::blocked_range< size_t >& r) const
{
    // Test packing data for sse vectorization
    for(size_t index = r.begin(); index < r.end(); ++index)
        rtcIntersect(m_scene->rtc_scene, m_data[index].rtc_ray);
}
コード例 #24
0
 void operator()( const tbb::blocked_range<size_t>& range ) const {
     for( size_t i=range.begin(); i!=range.end(); ++i ) {
         size_t n = my_vector.size();
         size_t k = n==0 ? 0 : i % (2*n+1);
         my_vector.grow_to_at_least(k+1);
         ASSERT( my_vector.size()>=k+1, NULL );
     }
 }
コード例 #25
0
 void operator()(const tbb::blocked_range<const_iterator>& range)
 {
     //Gotcha: don't use range-based for loop b/c need to pass iterators
     return_type Sum=MySum_;
     const_iterator end=range.end();
     for(const_iterator i=range.begin();i!=end;++i)Sum=Fxn_(Sum,Fxn_(i));
     MySum_=Sum;
 }
コード例 #26
0
 void operator()( const tbb::blocked_range<int>& range ) const
 {
     for ( int i = range.begin(); i != range.end(); ++i )
     {
         btBroadphasePair* pair = &mPairArray[ i ];
         mCallback( *pair, *mDispatcher, *mInfo );
     }
 }
コード例 #27
0
ファイル: parallel_grid.hpp プロジェクト: aoblet/TuttleOFX
 void operator()(const tbb::blocked_range<size_t>& blocks) const
 {
     BOOST_ASSERT(layers.size() == views.size());
     for(std::size_t block = blocks.begin(); block != blocks.end(); ++block)
     {
         view_t v = views[block];
         layers[block](v);
     }
 }
コード例 #28
0
    void operator() (tbb::blocked_range<int> const &r) const {

        float * dst = _oBuffer + r.begin() * _oStride;

        // reset normals to 0
        for (int i=r.begin(); i<r.end(); ++i, dst+=_oStride) {
            memset(dst, 0, 3*sizeof(float));
        }
    }
コード例 #29
0
 void operator() (const tbb::blocked_range<size_type> &range)
 {
     double sum = integral_;
     for (size_type i = range.begin(); i != range.end(); ++i) {
         sum += numeric_->integrate_segment(
                 grid_[i - 1], grid_[i], eval_);
     }
     integral_ = sum;
 }
コード例 #30
0
ファイル: main.cpp プロジェクト: linki/moinmoin
 void operator()(const tbb::blocked_range<int> &range) const
 {
    for (int i = range.begin(); i != range.end(); ++i)
    {
       printf("compute %d * %d\n", _source[i], _source[i]);
       
       _target[i] = _source[i] * _source[i];
    }
 }