ForEachCUDA

# Parallel Iterations

Include the Header
ForEachCUDA_1CUDAForEachIncludeTheHeader
Index-based Parallel Iterations
ForEachCUDA_1ForEachCUDAIndexBasedParallelFor
Iterator-based Parallel Iterations
ForEachCUDA_1ForEachCUDAIteratorBasedParallelIterations
Miscellaneous Items
ForEachCUDA_1ForEachCUDAMiscellaneousItems

tf::cudaFlow provides two template methods, tf::cudaFlow::for_each and tf::cudaFlow::for_each_index, for creating tasks to perform parallel iterations over a range of items.

# Include the Header

You need to include the header file, `taskflow/cuda/algorithm/for_each.hpp`, for creating a parallel-iteration task.

    #include<taskflow/cuda/algorithm/for_each.hpp>

# Index-based Parallel Iterations

Index-based parallel-for performs parallel iterations over a range `[first, last)` with the given `step` size. The task created by tf::cudaFlow::for_each_index(I first, I last, I step, C callable) represents a kernel of parallel execution for the following loop:

    //positivestep:first,first+step,first+2*step,...
    for(autoi=first;i<last;i+=step){
    callable(i);
    }
    //negativestep:first,first-step,first-2*step,...
    for(autoi=first;i>last;i+=step){
    callable(i);
    }

Each iteration `i` is independent of each other and is assigned one kernel thread to run the callable. Since the callable runs on GPU, it must be declared with a `__device__` specifier. The following example creates a kernel that assigns each entry of `gpu_data` to 1 over the range ``[0, 100) with step size 1.

    //assignseachelementingpu_datato1overtherange[0,100)withstepsize1
    cudaflow.for_each_index(0,100,1,[gpu_data]__device__(intidx){
    gpu_data[idx]=1;
    });

# Iterator-based Parallel Iterations

Iterator-based parallel-for performs parallel iterations over a range specified by two STL-styled iterators, `first` and `last`. The task created by tf::cudaFlow::for_each(I first, I last, C callable) represents a parallel execution of the following loop:

    for(autoi=first;i<last;i++){
    callable(*i);
    }

The two iterators, `first` and `last`, are typically two raw pointers to the first element and the next to the last element in the range in GPU memory space. The following example creates a `for_each` kernel that assigns each element in `gpu_data` to 1 over the range `[gpu_data, gpu_data + 1000)`.

    //assignseachelementto1overtherange[gpu_data,gpu_data+1000)
    cudaflow.for_each(gpu_data,gpu_data+1000,[]__device__(int&item){
    item=1;
    });

Each iteration is independent of each other and is assigned one kernel thread to run the callable. Since the callable runs on GPU, it must be declared with a `__device__` specifier.

# Miscellaneous Items

The parallel-iteration algorithms are also available in tf::cudaFlowCapturer::for_each and tf::cudaFlowCapturer::for_each_index.