#define CUDATOOLS_IMPLEMENTATION #include #include DEFINE_KERNEL(times2, const CudaTools::Array arr) { CudaTools::Array flat = arr.flattened(); BASIC_LOOP(arr.shape().items()) { flat[iThread] *= 2; } } DEFINE_KERNEL(times2double, const CudaTools::Array arr) { CudaTools::Array flat = arr.flattened(); BASIC_LOOP(arr.shape().items()) { flat[iThread] *= 2; } } int main() { CudaTools::Array arrRange = CudaTools::Array::range(0, 10); CudaTools::Array arrConst = CudaTools::Array::constant({10}, 1); CudaTools::Array arrLinspace = CudaTools::Array::linspace(0, 5, 10); CudaTools::Array arrComma({2, 2}); // 2x2 array. arrComma << 1, 2, 3, 4; // Comma initializer if needed. arrRange.updateDevice(); arrConst.updateDevice(); arrLinspace.updateDevice(); arrComma.updateDevice().wait(); std::cout << "Before Kernel:\n"; std::cout << arrRange << "\n" << arrConst << "\n" << arrLinspace << "\n" << arrComma << "\n"; // Call the kernel multiple times asynchronously. Note: since they share same // stream, they are not run in parallel, just queued on the device. // NOTE: Notice that a view is passed into the kernel, not the Array itself. KERNEL(times2, CudaTools::Kernel::basic(arrRange.shape().items()), arrRange.view()); KERNEL(times2, CudaTools::Kernel::basic(arrConst.shape().items()), arrConst.view()); KERNEL(times2double, CudaTools::Kernel::basic(arrLinspace.shape().items()), arrLinspace.view()); KERNEL(times2, CudaTools::Kernel::basic(arrComma.shape().items()), arrComma.view()).wait(); arrRange.updateHost(); arrConst.updateHost(); arrLinspace.updateHost(); arrComma.updateHost().wait(); // Same stream, so you should wait for the last call. std::cout << "After Kernel:\n"; std::cout << arrRange << "\n" << arrConst << "\n" << arrLinspace << "\n" << arrComma << "\n"; return 0; }