BabelStream/src/std-indices/STDIndicesStream.h
Tom Lin f77e43c6d5 Don't capture this implicitly
Relax const constraints on the range iterator
2022-07-28 16:23:07 +01:00

102 lines
2.9 KiB
C++

// Copyright (c) 2021 Tom Deakin and Tom Lin
// University of Bristol HPC
//
// For full license terms please see the LICENSE file distributed with this
// source code
#pragma once
#include "dpl_shim.h"
#include <iostream>
#include <stdexcept>
#include "Stream.h"
#define IMPLEMENTATION_STRING "STD (index-oriented)"
// A lightweight counting iterator which will be used by the STL algorithms
// NB: C++ <= 17 doesn't have this built-in, and it's only added later in ranges-v3 (C++2a) which this
// implementation doesn't target
template <typename N>
class ranged {
public:
class iterator {
friend class ranged;
public:
using difference_type = N;
using value_type = N;
using pointer = const N*;
using reference = N;
using iterator_category = std::random_access_iterator_tag;
// XXX This is not part of the iterator spec, it gets picked up by oneDPL if enabled.
// Without this, the DPL SYCL backend collects the iterator data on the host and copies to the device.
// This type is unused for any nother STL impl.
using is_passed_directly = std::true_type;
reference operator *() const { return i_; }
iterator &operator ++() { ++i_; return *this; }
iterator operator ++(int) { iterator copy(*this); ++i_; return copy; }
iterator &operator --() { --i_; return *this; }
iterator operator --(int) { iterator copy(*this); --i_; return copy; }
iterator &operator +=(N by) { i_+=by; return *this; }
value_type operator[](const difference_type &i) const { return i_ + i; }
difference_type operator-(const iterator &it) const { return i_ - it.i_; }
iterator operator+(const value_type v) const { return iterator(i_ + v); }
bool operator ==(const iterator &other) const { return i_ == other.i_; }
bool operator !=(const iterator &other) const { return i_ != other.i_; }
bool operator < (const iterator &other) const { return i_ < other.i_; }
protected:
explicit iterator(N start) : i_ (start) {}
private:
N i_;
};
[[nodiscard]] iterator begin() const { return begin_; }
[[nodiscard]] iterator end() const { return end_; }
ranged(N begin, N end) : begin_(begin), end_(end) {}
private:
iterator begin_;
iterator end_;
};
template <class T>
class STDIndicesStream : public Stream<T>
{
protected:
// Size of arrays
int array_size;
// induction range
ranged<int> range;
// Device side pointers
#ifdef USE_VECTOR
std::vector<T, Allocator<T>> a, b, c;
#else
T *a, *b, *c;
#endif
public:
STDIndicesStream(const int, int) noexcept;
~STDIndicesStream();
virtual void copy() override;
virtual void add() override;
virtual void mul() override;
virtual void triad() override;
virtual void nstream() override;
virtual T dot() override;
virtual void init_arrays(T initA, T initB, T initC) override;
virtual void read_arrays(std::vector<T>& a, std::vector<T>& b, std::vector<T>& c) override;
};