<commit_before>/*
Copyright (c) 2014-2015, <NAME>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/

//----------------------------------------------------------------------------
// views.hpp
//
// Provides specialized view of the data within a container.
//
// Author: <NAME>, Ph.D. (<EMAIL>)
//----------------------------------------------------------------------------

#pragma once
#ifndef ECUDA_VIEWS_HPP
#define ECUDA_VIEWS_HPP

#include <cstddef>
#include <vector>

#ifdef __CPP11_SUPPORTED__
#include <initializer_list>
#endif

#include "global.hpp"
#include "apiwrappers.hpp"
#include "iterators.hpp"
#include "device_ptr.hpp"
#include "striding_ptr.hpp"
#include "padded_ptr.hpp"

namespace ecuda {

struct __dimension_contiguous_tag {};
struct __dimension_noncontiguous_tag {};

struct __container_type_base_tag {};
struct __container_type_derived_tag {};

template<typename T,typename PointerType,typename DimensionType,typename ContainerType> struct __device_sequence_traits;
template<typename T,typename PointerType> struct __device_sequence_traits<T,PointerType,__dimension_contiguous_tag,__container_type_base_tag> {
	typedef typename PointerType::pointer pointer;
	typedef contiguous_device_iterator<T> iterator;
	typedef contiguous_device_iterator<const T> const_iterator;
};
template<typename T,typename PointerType> struct __device_sequence_traits<T,PointerType,__dimension_noncontiguous_tag,__container_type_base_tag> {
	typedef typename PointerType::pointer pointer;
	typedef device_iterator<T,PointerType> iterator;
	typedef device_iterator<const T,PointerType> const_iterator;
};
template<typename T,typename PointerType> struct __device_sequence_traits<T,PointerType,__dimension_contiguous_tag,__container_type_derived_tag> {
	typedef PointerType pointer;
	typedef contiguous_device_iterator<T> iterator;
	typedef contiguous_device_iterator<const T> const_iterator;
};
template<typename T,typename PointerType> struct __device_sequence_traits<T,PointerType,__dimension_noncontiguous_tag,__container_type_derived_tag> {
	typedef PointerType pointer;
	typedef device_iterator<T,PointerType> iterator;
	typedef device_iterator<const T,PointerType> const_iterator;
};

template<typename T,typename PointerType,typename RowDimensionType,typename ColumnDimensionType,typename ContainerType> struct __device_grid_traits;
template<typename T,typename PointerType,typename RowDimensionType,typename ColumnDimensionType> struct __device_grid_traits<T,PointerType,RowDimensionType,ColumnDimensionType,__container_type_base_tag> {
	typedef typename PointerType::pointer pointer;
	typedef device_iterator<T,PointerType> iterator;
	typedef device_iterator<const T,PointerType> const_iterator;
};
template<typename T,typename PointerType> struct __device_grid_traits<T,PointerType,__dimension_contiguous_tag,__dimension_contiguous_tag,__container_type_base_tag> {
	typedef typename PointerType::pointer pointer;
	typedef contiguous_device_iterator<T> iterator;
	typedef contiguous_device_iterator<const T> const_iterator;
};
template<typename T,typename PointerType,typename RowDimensionType,typename ColumnDimensionType> struct __device_grid_traits<T,PointerType,RowDimensionType,ColumnDimensionType,__container_type_derived_tag> {
	typedef PointerType pointer;
	typedef device_iterator<T,PointerType> iterator;
	typedef device_iterator<const T,PointerType> const_iterator;
};
template<typename T,typename PointerType> struct __device_grid_traits<T,PointerType,__dimension_contiguous_tag,__dimension_contiguous_tag,__container_type_derived_tag> {
	typedef PointerType pointer;
	typedef contiguous_device_iterator<T> iterator;
	typedef contiguous_device_iterator<const T> const_iterator;
};


template<typename T,typename PointerType=typename reference<T>::pointer_type,typename DimensionType=__dimension_contiguous_tag,typename ContainerType=__container_type_base_tag>
class __device_sequence
{
public:
	typedef T value_type;
	typedef typename __device_sequence_traits<T,PointerType,DimensionType,ContainerType>::pointer pointer;
	typedef value_type& reference;
	typedef const value_type& const_reference;
	typedef std::size_t size_type;
	typedef std::ptrdiff_t difference_type;

private:
	typedef PointerType managed_pointer;
	typedef DimensionType dimension_type;

public:
	typedef typename __device_sequence_traits<T,PointerType,DimensionType,ContainerType>::iterator iterator;
	typedef typename __device_sequence_traits<T,PointerType,DimensionType,ContainerType>::const_iterator const_iterator;
	typedef reverse_device_iterator<iterator> reverse_iterator;
	typedef reverse_device_iterator<const_iterator> const_reverse_iterator;

private:
	managed_pointer ptr;
	size_type length;

private:
	HOST DEVICE void fill( const value_type& value, __dimension_contiguous_tag ) {
		#ifdef __CUDA_ARCH__
		for( iterator iter = begin(); iter != end(); ++iter ) *iter = value;
		#else
		CUDA_CALL( cudaMemset<value_type>( data(), value, size() ) );
		#endif
	}

	HOST DEVICE void fill( const value_type& value, __dimension_noncontiguous_tag ) {
		#ifdef __CUDA_ARCH__
		for( iterator iter = begin(); iter != end(); ++iter ) *iter = value;
		#else
		throw cuda_error( cudaErrorInvalidDevicePointer, EXCEPTION_MSG("__device_sequence::fill cannot fill non-contiguous device memory from host") );
		#endif
	}

	template<class Iterator>
	HOST void copy_range_to( const_iterator first, const_iterator last, Iterator output, contiguous_device_iterator_tag, std::random_access_iterator_tag ) const {
		const typename std::iterator_traits<const_iterator>::difference_type n = last-first;
		CUDA_CALL( cudaMemcpy<typename std::remove_const<value_type>::type>( output.operator->(), first.operator->(), n, cudaMemcpyDeviceToHost ) );
	}

	template<class Iterator>
	HOST void copy_range_to( const_iterator first, const_iterator last, Iterator output, contiguous_device_iterator_tag, std::bidirectional_iterator_tag ) const {
		const typename std::iterator_traits<const_iterator>::difference_type n = last-first;
		std::vector< value_type, host_allocator<value_type> > v( n );
		CUDA_CALL( cudaMemcpy<typename std::remove_const<value_type>::type>( output.operator->(), &v.front(), n, cudaMemcpyDeviceToHost ) );
		std::copy( v.begin(), v.end(), output );
	}

	template<class Iterator> HOST inline void copy_range_to( const_iterator first, const_iterator last, Iterator output, contiguous_device_iterator_tag, std::forward_iterator_tag ) const { copy_range_to( first, last, output, std::bidirectional_iterator_tag() ); }
	template<class Iterator> HOST inline void copy_range_to( const_iterator first, const_iterator last, Iterator output, contiguous_device_iterator_tag, std::output_iterator_tag ) const { copy_range_to( first, last, output, std::bidirectional_iterator_tag() ); }

	template<class Iterator>
	HOST void copy_range_to( const_iterator first, const_iterator last, Iterator output, contiguous_device_iterator_tag, contiguous_device_iterator_tag ) const {
		const typename std::iterator_traits<const_iterator>::difference_type n = last-first;
		CUDA_CALL( cudaMemcpy<typename std::remove_const<value_type>::type>( output.operator->(), first.operator->(), n, cudaMemcpyDeviceToDevice ) );
	}


	template<class Iterator>
	HOST void copy_range_from( Iterator first, Iterator last, iterator output, std::random_access_iterator_tag, contiguous_device_iterator_tag ) {
		const typename std::iterator_traits<Iterator>::difference_type n = std::distance(first,last);
		CUDA_CALL( cudaMemcpy<typename std::remove_const<value_type>::type>( output.operator->(), first.operator->(), n, cudaMemcpyHostToDevice ) );
	}

	template<class Iterator>
	HOST void copy_range_from( Iterator first, Iterator last, iterator output, std::bidirectional_iterator_tag, contiguous_device_iterator_tag ) {
		std::vector< value_type, host_allocator<value_type> > v( first, last );
		CUDA_CALL( cudaMemcpy<typename std::remove_const<value_type>::type>( output.operator->(), &v.front(), v.size(), cudaMemcpyHostToDevice ) );
	}<commit_msg>tweaking sequence<commit_after>/*
Copyright (c) 2014-2015, <NAME>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/

//----------------------------------------------------------------------------
// views.hpp
//
// Provides specialized view of the data within a container.
//
// Author: <NAME>, Ph.D. (<EMAIL>)
//----------------------------------------------------------------------------

#pragma once
#ifndef ECUDA_VIEWS_HPP
#define ECUDA_VIEWS_HPP

#include <cstddef>
#include <vector>

#ifdef __CPP11_SUPPORTED__
#include <initializer_list>
#endif

#include "global.hpp"
#include "apiwrappers.hpp"
#include "iterators.hpp"
#include "device_ptr.hpp"
#include "striding_ptr.hpp"
#include "padded_ptr.hpp"

namespace ecuda {

struct __dimension_contiguous_tag {};
struct __dimension_noncontiguous_tag {};

struct __container_type_base_tag {};
struct __container_type_derived_tag {};

template<typename T,typename PointerType,typename DimensionType,typename ContainerType> struct __device_sequence_traits;
template<typename T,typename PointerType> struct __device_sequence_traits<T,PointerType,__dimension_contiguous_tag,__container_type_base_tag> {
	typedef typename PointerType::pointer pointer;
	typedef contiguous_device_iterator<T> iterator;
	typedef contiguous_device_iterator<const T> const_iterator;
};
template<typename T,typename PointerType> struct __device_sequence_traits<T,PointerType,__dimension_noncontiguous_tag,__container_type_base_tag> {
	typedef typename PointerType::pointer pointer;
	typedef device_iterator<T,PointerType> iterator;
	typedef device_iterator<const T,PointerType> const_iterator;
};
template<typename T,typename PointerType> struct __device_sequence_traits<T,PointerType,__dimension_contiguous_tag,__container_type_derived_tag> {
	typedef PointerType pointer;
	typedef contiguous_device_iterator<T> iterator;
	typedef contiguous_device_iterator<const T> const_iterator;
};
template<typename T,typename PointerType> struct __device_sequence_traits<T,PointerType,__dimension_noncontiguous_tag,__container_type_derived_tag> {
	typedef PointerType pointer;
	typedef device_iterator<T,PointerType> iterator;
	typedef device_iterator<const T,PointerType> const_iterator;
};

template<typename T,typename PointerType,typename RowDimensionType,typename ColumnDimensionType,typename ContainerType> struct __device_grid_traits;
template<typename T,typename PointerType,typename RowDimensionType,typename ColumnDimensionType> struct __device_grid_traits<T,PointerType,RowDimensionType,ColumnDimensionType,__container_type_base_tag> {
	typedef typename PointerType::pointer pointer;
	typedef device_iterator<T,PointerType> iterator;
	typedef device_iterator<const T,PointerType> const_iterator;
};
template<typename T,typename PointerType> struct __device_grid_traits<T,PointerType,__dimension_contiguous_tag,__dimension_contiguous_tag,__container_type_base_tag> {
	typedef typename PointerType::pointer pointer;
	typedef contiguous_device_iterator<T> iterator;
	typedef contiguous_device_iterator<const T> const_iterator;
};
template<typename T,typename PointerType,typename RowDimensionType,typename ColumnDimensionType> struct __device_grid_traits<T,PointerType,RowDimensionType,ColumnDimensionType,__container_type_derived_tag> {
	typedef PointerType pointer;
	typedef device_iterator<T,PointerType> iterator;
	typedef device_iterator<const T,PointerType> const_iterator;
};
template<typename T,typename PointerType> struct __device_grid_traits<T,PointerType,__dimension_contiguous_tag,__dimension_contiguous_tag,__container_type_derived_tag> {
	typedef PointerType pointer;
	typedef contiguous_device_iterator<T> iterator;
	typedef contiguous_device_iterator<const T> const_iterator;
};


template<typename T,typename PointerType=typename reference<T>::pointer_type,typename DimensionType=__dimension_contiguous_tag,typename ContainerType=__container_type_base_tag>
class __device_sequence
{
public:
	typedef T value_type;
	typedef typename __device_sequence_traits<T,PointerType,DimensionType,ContainerType>::pointer pointer;
	typedef value_type& reference;
	typedef const value_type& const_reference;
	typedef std::size_t size_type;
	typedef std::ptrdiff_t difference_type;

private:
	typedef PointerType managed_pointer;
	typedef DimensionType dimension_type;

public:
	typedef typename __device_sequence_traits<T,PointerType,DimensionType,ContainerType>::iterator iterator;
	typedef typename __device_sequence_traits<T,PointerType,DimensionType,ContainerType>::const_iterator const_iterator;
	typedef reverse_device_iterator<iterator> reverse_iterator;
	typedef reverse_device_iterator<const_iterator> const_reverse_iterator;

private:
	managed_pointer ptr;
	size_type length;

private:
	HOST DEVICE void fill( const value_type& value, __dimension_contiguous_tag ) {
		#ifdef __CUDA_ARCH__
		for( iterator iter = begin(); iter != end(); ++iter ) *iter = value;
		#else
		CUDA_CALL( cudaMemset<value_type>( data(), value, size() ) );
		#endif
	}

	HOST DEVICE void fill( const value_type& value, __dimension_noncontiguous_tag ) {
		#ifdef __CUDA_ARCH__
		for( iterator iter = begin(); iter != end(); ++iter ) *iter = value;
		#else
		throw cuda_error( cudaErrorInvalidDevicePointer, EXCEPTION_MSG("__device_sequence::fill cannot fill non-contiguous device memory from host") );
		#endif
	}

	template<class Iterator>
	HOST void copy_range_to( const_iterator first, const_iterator last, Iterator output, contiguous_device_iterator_tag, std::random_access_iterator_tag ) const {
		const typename std::iterator_traits<const_iterator>::difference_type n = last-first;
		CUDA_CALL( cudaMemcpy<typename std::remove_const<value_type>::type>( output.operator->(), first.operator->(), n, cudaMemcpyDeviceToHost ) );
	}

	template<class Iterator>
	HOST void copy_range_to( const_iterator first, const_iterator last, Iterator output, contiguous_device_iterator_tag, std::bidirectional_iterator_tag ) const {
		const typename std::iterator_traits<const_iterator>::difference_type n = last-first;
		std::vector< value_type, host_allocator<value_type> > v( n );
		CUDA_CALL( cudaMemcpy<typename std::remove_const<value_type>::type>( output.operator->(), &v.front(), n, cudaMemcpyDeviceToHost ) );
		std::copy( v.begin(), v.end(), output );
	}

	template<class Iterator> HOST inline void copy_range_to( const_iterator first, const_iterator last, Iterator output, contiguous_device_iterator_tag, std::forward_iterator_tag ) const { copy_range_to( first, last, output, std::bidirectional_iterator_tag() ); }
	template<class Iterator> HOST inline void copy_range_to( const_iterator first, const_iterator last, Iterator output, contiguous_device_iterator_tag, std::output_iterator_tag ) const { copy_range_to( first, last, output, std::bidirectional_iterator_tag() ); }

	template<class Iterator>
	HOST void copy_range_to( const_iterator first, const_iterator last, Iterator output, contiguous_device_iterator_tag, contiguous_device_iterator_tag ) const {
		const typename std::iterator_traits<const_iterator>::difference_type n = last-first;
		CUDA_CALL( cudaMemcpy<typename std::remove_const<value_type>::type>( output.operator->(), first.operator->(), n, cudaMemcpyDeviceToDevice ) );
	}


	template<class Iterator>
	HOST void copy_range_from( Iterator first, Iterator last, iterator output, std::random_access_iterator_tag, contiguous_device_iterator_tag ) {
		const typename std::iterator_traits<Iterator>::difference_type n = std::distance(first,last);
		std::cerr << "first.operator->()=" << first.operator->() << std::endl;
		std::cerr << "output.operator->()=" << output.operator->() << std::endl;
		std::cerr << "n=" << n << std::endl;
		CUDA_CALL( cudaMemcpy<typename std::remove_const<value_type>::type>( output.operator->(), first.operator->(), n, cudaMemcpyHostToDevice ) );
	}

	template<class Iterator>
	HOST void copy_range_from( Iterator first, Iterator last, iterator output, std::bidirectional_iterator_tag, contiguous_device_iterator_tag ) {
		std::vector< value_type, host_allocator<value_type> > v( first, last );
		CUDA_CALL( cudaMemcpy<typename std::remove_const<value_type>::type>( output.operator->(), &v.front(), v.size(), cudaMemcpyHostToDevice ) );
	}
{'fraction_non_alphanumeric': 0.09838988828866628, 'fraction_numerical': 0.0012587192531599099, 'mean_word_length': 7.138284250960307, 'pattern_counts': {'":': 0, '<': 167, '<?xml version=': 0, '>': 169, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6779051', 'n_tokens_mistral': 5754, 'n_tokens_neox': 5279, 'n_words': 1439}