 #include <cuda/api_wrappers.hpp>
 
 #include <iostream>
+#include <numeric>
 #include <limits>
 
 using std::size_t;

}

template<class Device>
void array_3d_example(Device& device, size_t w, size_t h, size_t d)
{
	namespace grid = cuda::grid;
	const cuda::array::dimensions_t<3> dims = {w, h, d};

	cuda::array::array_t<float, 3> arr(device, dims);
	auto ptr_in = cuda::memory::managed::make_unique<float[]>(arr.size());
	ptr_in[5] = 6;
	auto ptr_out = cuda::memory::managed::make_unique<float[]>(arr.size());
	cuda::memory::copy(arr, ptr_in.get());
	cuda::texture_view tv(arr);

		}
		std::cout << std::endl;
	}
	for (size_t k = 0; k < arr.size(); ++k) {
		if (ptr_out[k] != k) {
			std::cout << "ERROR: values were not correctly copied!" << std::endl;
		}
	}

	// copy between arrays and memory spaces
	cuda::array::array_t<float, 2> other_arr(device, dims);
	cuda::memory::copy(other_arr, ptr_out.get());
	cuda::memory::copy(ptr_in.get(), other_arr);
	for (size_t k = 0; k < arr.size(); ++k) {
		if (ptr_in[k] != k) {
			std::cout << "ERROR: values were not correctly copied!" << std::endl;
		}
	}
	
	// also asynchronously
	auto stream = device.create_stream(cuda::stream::async);
	cuda::memory::async::copy(other_arr, ptr_out.get(), stream);
	cuda::memory::async::copy(ptr_in.get(), other_arr, stream);
	device.synchronize();
	for (size_t k = 0; k < arr.size(); ++k) {
		if (ptr_in[k] != k) {
			std::cout << "ERROR: values were not correctly copied!" << std::endl;
		}
	}
}

int main()
