[CCCL] 瘦身 + 补全: 移除 cudax/python/libcudacxx-tests 冗余文件, 新增 c2h 测试助手 + cmake 构建系统 + 8 个 CUDA thrust examples

变更摘要:
- 删除: cudax/ (783 files, 7.2M) — 实验性组件,竞赛不需要
- 删除: python/ (226 files, 2.0M) — Python 绑定,竞赛不需要
- 删除: libcudacxx/{test,benchmarks,codegen,cmake,share} (4432 files, 31M)
  保留: libcudacxx/include/ (1463 headers, cuda::std 编译依赖)
- 新增: c2h/ (27 files) — CUB Catch2 测试辅助头文件,编译 243 个测试必需
- 新增: cmake/ (29 files) — CCCL 原生 CMake 构建系统
- 新增: thrust/examples/cuda/ (7 files) + cpp_integration/ (1 file)
  async_reduce, custom_temporary_allocation, explicit_cuda_stream,
  global_device_vector, range_view, unwrap_pointer, wrap_pointer, device

结果: cccl_upstream 从 74M→35M (瘦身 53%), 核心内容 100% 保留:
  27/27 tuning headers, 78 benchmarks, 243 tests,
  60 thrust examples, 18 CUB examples, 全部编译头文件
This commit is contained in:
muh-bot
2026-08-03 12:39:26 +00:00
parent a2a5dd8f00
commit 24ef6a91b5
5439 changed files with 0 additions and 719516 deletions

View File

@@ -1,47 +0,0 @@
//===----------------------------------------------------------------------===//
//
// Part of CUDASTF in CUDA C++ Core Libraries,
// under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES.
//
//===----------------------------------------------------------------------===//
/**
* @file
*
* @brief Test reduce access mode when we encounter an empty shape to ensure we do initialize values
*
*/
#include <cuda/experimental/stf.cuh>
using namespace cuda::experimental::stf;
template <typename context_t>
void run()
{
context_t ctx;
auto lsum = ctx.logical_data(shape_of<scalar_view<int>>());
auto lmax = ctx.logical_data(shape_of<scalar_view<int>>());
ctx.parallel_for(box(0), lsum.reduce(reducer::sum<int>{}), lmax.reduce(reducer::maxval<int>{}))
->*[] __device__(size_t, auto&, auto&) {
// This is never going to be called because this is an empty shape
};
auto res_sum = ctx.wait(lsum);
auto res_max = ctx.wait(lmax);
ctx.finalize();
_CCCL_ASSERT(res_sum == 0, "Invalid result");
_CCCL_ASSERT(res_max == ::std::numeric_limits<int>::lowest(), "Invalid result");
}
int main()
{
run<stream_ctx>();
run<graph_ctx>();
}

View File

@@ -1,254 +0,0 @@
//===----------------------------------------------------------------------===//
//
// Part of CUDASTF in CUDA C++ Core Libraries,
// under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES.
//
//===----------------------------------------------------------------------===//
#include <cuda/experimental/__stf/stream/stream_ctx.cuh>
#include <cuda/experimental/__stf/utility/dimensions.cuh>
using namespace cuda::experimental::stf;
// FIXME : MSVC has trouble with box constructors
#if !_CCCL_COMPILER(MSVC)
void write_vtk_2D(const std::string& filename, slice<const double, 3> Ez, double dx, double dy, double /*unused*/)
{
FILE* f = fopen(filename.c_str(), "w");
const size_t pos_z = Ez.extent(2) / 2;
const size_t nx = Ez.extent(0);
const size_t size = Ez.extent(0) * Ez.extent(1);
fprintf(f, "# vtk DataFile Version 3.0\n");
fprintf(f, "vtk output\n");
fprintf(f, "ASCII\n");
fprintf(f, "DATASET UNSTRUCTURED_GRID\n");
fprintf(f, "POINTS %ld float\n", 4 * size);
for (size_t y = 0; y < Ez.extent(1); y++)
{
for (size_t x = 0; x < Ez.extent(0); x++)
{
fprintf(f, "%lf %lf 0.0\n", dx * static_cast<float>(x + 0), dy * static_cast<float>(y + 0));
fprintf(f, "%lf %lf 0.0\n", dx * static_cast<float>(x + 1), dy * static_cast<float>(y + 0));
fprintf(f, "%lf %lf 0.0\n", dx * static_cast<float>(x + 1), dy * static_cast<float>(y + 1));
fprintf(f, "%lf %lf 0.0\n", dx * static_cast<float>(x + 0), dy * static_cast<float>(y + 1));
}
}
fprintf(f, "CELLS %ld %ld\n", size, 5 * size);
size_t cell_id = 0;
for (size_t y = 0; y < Ez.extent(1); y++)
{
for (size_t x = 0; x < Ez.extent(0); x++)
{
const size_t point_offset = cell_id * 4;
fprintf(f,
"4 %d %d %d %d\n",
(int) (point_offset + 0),
(int) (point_offset + 1),
(int) (point_offset + 2),
(int) (point_offset + 3));
cell_id++;
}
}
fprintf(f, "CELL_TYPES %ld\n", size);
for (size_t ii = 0; ii < size; ii++)
{
fprintf(f, "5\n");
}
fprintf(f, "CELL_DATA %ld\n", size);
fprintf(f, "SCALARS Ez double 1\n");
fprintf(f, "LOOKUP_TABLE default\n");
for (size_t y = 0; y < Ez.extent(1); y++)
{
for (size_t x = 0; x < Ez.extent(0); x++)
{
fprintf(f, "%lf\n", Ez(x, y, pos_z));
}
}
fclose(f);
}
// Define the source function
__device__ double Source(double t, double x, double y, double z)
{
constexpr double pi = 3.14159265358979323846;
constexpr double freq = 1e9;
constexpr double omega = (2 * pi * freq);
constexpr double wavelength = 3e8 / freq;
constexpr double k = 2 * pi / wavelength;
return sin(k * x - omega * t);
}
#endif // !_CCCL_COMPILER(MSVC)
int main([[maybe_unused]] int argc, [[maybe_unused]] char** argv)
{
#if !_CCCL_COMPILER(MSVC)
stream_ctx ctx;
// Domain dimensions
const size_t SIZE_X = 100;
const size_t SIZE_Y = 100;
const size_t SIZE_Z = 100;
// Grid spacing
const double DX = 0.01;
const double DY = 0.01;
const double DZ = 0.01;
// Define the electric and magnetic fields
auto data_shape = shape_of<slice<double, 3>>(SIZE_X, SIZE_Y, SIZE_Z);
auto lEx = ctx.logical_data(data_shape);
auto lEy = ctx.logical_data(data_shape);
auto lEz = ctx.logical_data(data_shape);
auto lHx = ctx.logical_data(data_shape);
auto lHy = ctx.logical_data(data_shape);
auto lHz = ctx.logical_data(data_shape);
// Define the permittivity and permeability of the medium
auto lepsilon = ctx.logical_data(data_shape);
auto lmu = ctx.logical_data(data_shape);
const double EPSILON = 8.85e-12; // Permittivity of free space
const double MU = 1.256e-6; // Permeability of free space
// CFL condition DT <= min(DX, DY, DZ) * sqrt(epsilon_max * mu_max)
double DT = 0.25 * min(min(DX, DY), DZ) * sqrt(EPSILON * MU);
// Initialize E
ctx.parallel_for(data_shape, lEx.write(), lEy.write(), lEz.write())
->*[] _CCCL_DEVICE(size_t i, size_t j, size_t k, auto Ex, auto Ey, auto Ez) {
Ex(i, j, k) = 0.0;
Ey(i, j, k) = 0.0;
Ez(i, j, k) = 0.0;
};
// Initialize H
ctx.parallel_for(data_shape, lHx.write(), lHy.write(), lHz.write())
->*[] _CCCL_DEVICE(size_t i, size_t j, size_t k, auto Hx, auto Hy, auto Hz) {
Hx(i, j, k) = 0.0;
Hy(i, j, k) = 0.0;
Hz(i, j, k) = 0.0;
};
// Initialize permittivity and permeability fields
ctx.parallel_for(data_shape, lepsilon.write(), lmu.write())
->*[=] _CCCL_DEVICE(size_t i, size_t j, size_t k, auto epsilon, auto mu) {
epsilon(i, j, k) = EPSILON;
mu(i, j, k) = MU;
};
// Set the source function at the center of the grid
const size_t center_x = SIZE_X / 2;
const size_t center_y = SIZE_Y / 2;
const size_t center_z = SIZE_Z / 2;
// Initialize the time loop
size_t timesteps = 10;
if (argc > 1)
{
timesteps = (size_t) atol(argv[1]);
}
// No output by default
int64_t output_freq = -1;
if (argc > 2)
{
output_freq = (int64_t) atol(argv[2]);
}
/* Index shapes for Electric fields, Magnetic fields, and the indices where there is a source */
box<3> Es({1ul, SIZE_X - 1}, {1ul, SIZE_Y - 1}, {1ul, SIZE_Z - 1});
box<3> Hs({0ul, SIZE_X - 1}, {0ul, SIZE_Y - 1}, {0ul, SIZE_Z - 1});
box<3> source_s({center_x, center_x + 1}, {center_y, center_y + 1}, {center_z, center_z + 1});
for (size_t n = 0; n < timesteps; n++)
{
// Update the electric fields
// Update Ex
ctx.parallel_for(Es, lEx.rw(), lHy.read(), lHz.read(), lepsilon.read())
->*[=]
_CCCL_DEVICE(size_t i, size_t j, size_t k, auto Ex, auto Hy, auto Hz, auto epsilon) {
Ex(i, j, k) = Ex(i, j, k)
+ (DT / (epsilon(i, j, k) * DX)) * (Hz(i, j, k) - Hz(i, j - 1, k) - Hy(i, j, k) + Hy(i, j, k - 1));
};
// Update Ey
ctx.parallel_for(Es, lEy.rw(), lHx.read(), lHz.read(), lepsilon.read())
->*[=]
_CCCL_DEVICE(size_t i, size_t j, size_t k, auto Ey, auto Hx, auto Hz, auto epsilon) {
Ey(i, j, k) = Ey(i, j, k)
+ (DT / (epsilon(i, j, k) * DY)) * (Hx(i, j, k) - Hx(i, j, k - 1) - Hz(i, j, k) + Hz(i - 1, j, k));
};
// Update Ez
ctx.parallel_for(Es, lEz.rw(), lHx.read(), lHy.read(), lepsilon.read())
->*[=]
_CCCL_DEVICE(size_t i, size_t j, size_t k, auto Ez, auto Hx, auto Hy, auto epsilon) {
Ez(i, j, k) = Ez(i, j, k)
+ (DT / (epsilon(i, j, k) * DZ)) * (Hy(i, j, k) - Hy(i - 1, j, k) - Hx(i, j, k) + Hx(i, j - 1, k));
};
// Add the source function at the center of the grid
ctx.parallel_for(source_s, lEz.rw())->*[=] _CCCL_DEVICE(size_t i, size_t j, size_t k, auto Ez) {
Ez(i, j, k) = Ez(i, j, k) + Source(n * DT, i * DX, j * DY, k * DZ);
};
// Update the magnetic fields
// Update Hx
ctx.parallel_for(Hs, lHx.rw(), lEy.read(), lEz.read(), lmu.read())
->*[=] _CCCL_DEVICE(size_t i, size_t j, size_t k, auto Hx, auto Ey, auto Ez, auto mu) {
Hx(i, j, k) = Hx(i, j, k)
- (DT / (mu(i, j, k) * DY)) * (Ez(i, j + 1, k) - Ez(i, j, k) - Ey(i, j, k + 1) + Ey(i, j, k));
};
// Update Hy
ctx.parallel_for(Hs, lHy.rw(), lEx.read(), lEz.read(), lmu.read())
->*[=] _CCCL_DEVICE(size_t i, size_t j, size_t k, auto Hy, auto Ex, auto Ez, auto mu) {
Hy(i, j, k) = Hy(i, j, k)
- (DT / (mu(i, j, k) * DZ)) * (Ex(i, j, k + 1) - Ex(i, j, k) - Ez(i + 1, j, k) + Ez(i, j, k));
};
// Update Hz
ctx.parallel_for(Hs, lHz.rw(), lEx.read(), lEy.read(), lmu.read())
->*[=] _CCCL_DEVICE(size_t i, size_t j, size_t k, auto Hz, auto Ex, auto Ey, auto mu) {
Hz(i, j, k) = Hz(i, j, k)
- (DT / (mu(i, j, k) * DX)) * (Ey(i + 1, j, k) - Ey(i, j, k) - Ex(i, j + 1, k) + Ex(i, j, k));
};
if (output_freq > 0)
{
ctx.host_launch(lEz.read())->*[=](auto Ez) {
// Output the electric field at the center of the grid
fprintf(stderr, "%ld\t%le\n", n, Ez(center_x, center_y, center_z));
if (output_freq > 0 && n % output_freq == 0)
{
std::string filename = "Ez" + std::to_string(n) + ".vtk";
// Dump a 2D slice of Ez in VTK
write_vtk_2D(filename, Ez, DX, DY, DZ);
}
};
}
}
ctx.finalize();
#endif // !_CCCL_COMPILER(MSVC)
}

View File

@@ -1,300 +0,0 @@
//===----------------------------------------------------------------------===//
//
// Part of CUDASTF in CUDA C++ Core Libraries,
// under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES.
//
//===----------------------------------------------------------------------===//
/**
* @file
*
* @brief Reference OpenACC implementation of the FDTD example
*/
#include <string>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define Ex(i, j, k) (Ex_array[(i) + (j) * SIZE_X + (k) * SIZE_X * SIZE_Y])
#define Ey(i, j, k) (Ey_array[(i) + (j) * SIZE_X + (k) * SIZE_X * SIZE_Y])
#define Ez(i, j, k) (Ez_array[(i) + (j) * SIZE_X + (k) * SIZE_X * SIZE_Y])
#define Hx(i, j, k) (Hx_array[(i) + (j) * SIZE_X + (k) * SIZE_X * SIZE_Y])
#define Hy(i, j, k) (Hy_array[(i) + (j) * SIZE_X + (k) * SIZE_X * SIZE_Y])
#define Hz(i, j, k) (Hz_array[(i) + (j) * SIZE_X + (k) * SIZE_X * SIZE_Y])
#define mu(i, j, k) (mu_array[(i) + (j) * SIZE_X + (k) * SIZE_X * SIZE_Y])
#define epsilon(i, j, k) (epsilon_array[(i) + (j) * SIZE_X + (k) * SIZE_X * SIZE_Y])
void write_vtk_2D(
const std::string& filename,
double* Ez_array,
double dx,
double dy,
double dz,
size_t SIZE_X,
size_t SIZE_Y,
size_t SIZE_Z)
{
FILE* f = fopen(filename.c_str(), "w");
const size_t pos_z = SIZE_Z / 2;
const size_t size = SIZE_X * SIZE_Y;
fprintf(f, "# vtk DataFile Version 3.0\n");
fprintf(f, "vtk output\n");
fprintf(f, "ASCII\n");
fprintf(f, "DATASET UNSTRUCTURED_GRID\n");
fprintf(f, "POINTS %ld float\n", 4 * size);
for (size_t y = 0; y < SIZE_Y; y++)
{
for (size_t x = 0; x < SIZE_X; x++)
{
fprintf(f, "%lf %lf 0.0\n", dx * static_cast<float>(x + 0), dy * static_cast<float>(y + 0));
fprintf(f, "%lf %lf 0.0\n", dx * static_cast<float>(x + 1), dy * static_cast<float>(y + 0));
fprintf(f, "%lf %lf 0.0\n", dx * static_cast<float>(x + 1), dy * static_cast<float>(y + 1));
fprintf(f, "%lf %lf 0.0\n", dx * static_cast<float>(x + 0), dy * static_cast<float>(y + 1));
}
}
fprintf(f, "CELLS %ld %ld\n", size, 5 * size);
size_t cell_id = 0;
for (size_t y = 0; y < SIZE_Y; y++)
{
for (size_t x = 0; x < SIZE_X; x++)
{
const size_t point_offset = cell_id * 4;
fprintf(f,
"4 %d %d %d %d\n",
(int) (point_offset + 0),
(int) (point_offset + 1),
(int) (point_offset + 2),
(int) (point_offset + 3));
cell_id++;
}
}
fprintf(f, "CELL_TYPES %ld\n", size);
for (size_t ii = 0; ii < size; ii++)
{
fprintf(f, "5\n");
}
fprintf(f, "CELL_DATA %ld\n", size);
fprintf(f, "SCALARS Ez double 1\n");
fprintf(f, "LOOKUP_TABLE default\n");
for (size_t y = 0; y < SIZE_Y; y++)
{
for (size_t x = 0; x < SIZE_X; x++)
{
fprintf(f, "%lf\n", Ez(x, y, pos_z));
}
}
fclose(f);
}
// Define the source function
double Source(double t, double x, double y, double z)
{
const double pi = 3.14159265358979323846;
const double freq = 1e9;
const double omega = (2 * pi * freq);
const double wavelength = 3e8 / freq;
const double k = 2 * pi / wavelength;
return sin(k * x - omega * t);
}
int main(int argc, char** argv)
{
// Domain dimensions
const size_t SIZE_X = 100;
const size_t SIZE_Y = 100;
const size_t SIZE_Z = 100;
// Grid spacing
const double DX = 0.01;
const double DY = 0.01;
const double DZ = 0.01;
// Define the electric and magnetic fields
double* Ex_array = new double[SIZE_X * SIZE_Y * SIZE_Z];
double* Ey_array = new double[SIZE_X * SIZE_Y * SIZE_Z];
double* Ez_array = new double[SIZE_X * SIZE_Y * SIZE_Z];
double* Hx_array = new double[SIZE_X * SIZE_Y * SIZE_Z];
double* Hy_array = new double[SIZE_X * SIZE_Y * SIZE_Z];
double* Hz_array = new double[SIZE_X * SIZE_Y * SIZE_Z];
// Define the permittivity and permeability of the medium
double* epsilon_array = new double[SIZE_X * SIZE_Y * SIZE_Z];
double* mu_array = new double[SIZE_X * SIZE_Y * SIZE_Z];
const double EPSILON = 8.85e-12; // Permittivity of free space
const double MU = 1.256e-6; // Permeability of free space
// CFL condition DT <= min(DX, DY, DZ) * sqrt(epsilon_max * mu_max)
double DT = 0.25 * std::min(std::min(DX, DY), DZ) * sqrt(EPSILON * MU);
// Initialize the fields, permittivity, permeability, and conductivity
#pragma acc parallel loop collapse(3)
for (size_t k = 0; k < SIZE_Z; k++)
{
for (size_t j = 0; j < SIZE_Y; j++)
{
for (size_t i = 0; i < SIZE_X; i++)
{
Ex(i, j, k) = 0.0;
Ey(i, j, k) = 0.0;
Ez(i, j, k) = 0.0;
Hx(i, j, k) = 0.0;
Hy(i, j, k) = 0.0;
Hz(i, j, k) = 0.0;
mu(i, j, k) = MU;
epsilon(i, j, k) = EPSILON;
}
}
}
// Set the source function at the center of the grid
const size_t center_x = SIZE_X / 2;
const size_t center_y = SIZE_Y / 2;
const size_t center_z = SIZE_Z / 2;
// Initialize the time loop
size_t timesteps = 1000;
if (argc > 1)
{
timesteps = (size_t) atol(argv[1]);
}
// No output by default
ssize_t output_freq = -1;
if (argc > 2)
{
output_freq = (ssize_t) atol(argv[2]);
}
for (size_t n = 0; n < timesteps; n++)
{
// Update the electric fields
// Update Ex
#pragma acc parallel loop collapse(3) async(1)
for (size_t k = 1; k < SIZE_Z - 1; k++)
{
for (size_t j = 1; j < SIZE_Y - 1; j++)
{
for (size_t i = 1; i < SIZE_X - 1; i++)
{
Ex(i, j, k) =
Ex(i, j, k)
+ (DT / (epsilon(i, j, k) * DX)) * (Hz(i, j, k) - Hz(i, j - 1, k) - Hy(i, j, k) + Hy(i, j, k - 1));
}
}
}
#pragma acc parallel loop collapse(3) async(2)
for (size_t k = 1; k < SIZE_Z - 1; k++)
{
for (size_t j = 1; j < SIZE_Y - 1; j++)
{
for (size_t i = 1; i < SIZE_X - 1; i++)
{
Ey(i, j, k) =
Ey(i, j, k)
+ (DT / (epsilon(i, j, k) * DY)) * (Hx(i, j, k) - Hx(i, j, k - 1) - Hz(i, j, k) + Hz(i - 1, j, k));
}
}
}
#pragma acc parallel loop collapse(3) async(3)
for (size_t k = 1; k < SIZE_Z - 1; k++)
{
for (size_t j = 1; j < SIZE_Y - 1; j++)
{
for (size_t i = 1; i < SIZE_X - 1; i++)
{
Ez(i, j, k) =
Ez(i, j, k)
+ (DT / (epsilon(i, j, k) * DZ)) * (Hy(i, j, k) - Hy(i - 1, j, k) - Hx(i, j, k) + Hx(i, j - 1, k));
// Add the source function at the center of the grid
if (i == center_x && j == center_y && k == center_z)
{
Ez(i, j, k) = Ez(i, j, k) + Source(n * DT, i * DX, j * DY, k * DZ);
}
}
}
}
#pragma acc wait(1)
#pragma acc wait(2)
#pragma acc wait(3)
#pragma acc parallel loop collapse(3) async(1)
for (size_t k = 0; k < SIZE_Z - 1; k++)
{
for (size_t j = 0; j < SIZE_Y - 1; j++)
{
for (size_t i = 0; i < SIZE_X - 1; i++)
{
Hx(i, j, k) =
Hx(i, j, k) - (DT / (mu(i, j, k) * DY)) * (Ez(i, j + 1, k) - Ez(i, j, k) - Ey(i, j, k + 1) + Ey(i, j, k));
}
}
}
#pragma acc parallel loop collapse(3) async(2)
for (size_t k = 0; k < SIZE_Z - 1; k++)
{
for (size_t j = 0; j < SIZE_Y - 1; j++)
{
for (size_t i = 0; i < SIZE_X - 1; i++)
{
Hy(i, j, k) =
Hy(i, j, k) - (DT / (mu(i, j, k) * DZ)) * (Ex(i, j, k + 1) - Ex(i, j, k) - Ez(i + 1, j, k) + Ez(i, j, k));
}
}
}
#pragma acc parallel loop collapse(3) async(3)
for (size_t k = 0; k < SIZE_Z - 1; k++)
{
for (size_t j = 0; j < SIZE_Y - 1; j++)
{
for (size_t i = 0; i < SIZE_X - 1; i++)
{
Hz(i, j, k) =
Hz(i, j, k) - (DT / (mu(i, j, k) * DX)) * (Ey(i + 1, j, k) - Ey(i, j, k) - Ex(i, j + 1, k) + Ex(i, j, k));
}
}
}
#pragma acc wait(1)
#pragma acc wait(2)
#pragma acc wait(3)
if (output_freq > 0)
{
// Output the electric field at the center of the grid
fprintf(stderr, "%ld\t%le\n", n, Ez(center_x, center_y, center_z));
if (output_freq > 0 && n % output_freq == 0)
{
std::string filename = "Ez" + std::to_string(n) + ".vtk";
// Dump a 2D slice of Ez in VTK
write_vtk_2D(filename, Ez_array, DX, DY, DZ, SIZE_X, SIZE_Y, SIZE_Z);
}
}
}
return 0;
}

View File

@@ -1,82 +0,0 @@
//===----------------------------------------------------------------------===//
//
// Part of CUDASTF in CUDA C++ Core Libraries,
// under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES.
//
//===----------------------------------------------------------------------===//
#include <cuda/experimental/__places/partitions/tiled_partition.cuh>
#include <cuda/experimental/__stf/stream/stream_ctx.cuh>
using namespace cuda::experimental::stf;
template <typename T>
__global__ void axpy(size_t start, size_t cnt, T a, const T* x, T* y)
{
int tid = blockIdx.x * blockDim.x + threadIdx.x;
int nthreads = gridDim.x * blockDim.x;
for (int ind = tid; ind < cnt; ind += nthreads)
{
y[ind + start] += a * x[ind + start];
}
}
double X0(size_t i)
{
return sin((double) i);
}
double Y0(size_t i)
{
return cos((double) i);
}
int main()
{
stream_ctx ctx;
const int N = 1024 * 1024 * 32;
double *X, *Y;
X = new double[N];
Y = new double[N];
for (size_t ind = 0; ind < N; ind++)
{
X[ind] = X0(ind);
Y[ind] = Y0(ind);
}
auto handle_X = ctx.logical_data(X, {N});
auto handle_Y = ctx.logical_data(Y, {N});
auto all_devs = exec_place::all_devices();
double alpha = 3.14;
/* Compute Y = Y + alpha X */
ctx.parallel_for(tiled_partition<1024 * 1024>(), all_devs, handle_X.shape(), handle_X.read(), handle_Y.rw())
->*[=] _CCCL_DEVICE(size_t i, auto sX, auto sY) {
sY(i) += alpha * sX(i);
};
/* Check the result on the host */
ctx.task(exec_place::host(), handle_X.read(), handle_Y.read())->*[&](cudaStream_t s, auto sX, auto sY) {
cuda_safe_call(cudaStreamSynchronize(s));
for (size_t ind = 0; ind < N; ind++)
{
// Y should be Y0 + alpha X0
EXPECT(fabs(sY(ind) - (Y0(ind) + alpha * X0(ind))) < 0.0001);
// X should be X0
EXPECT(fabs(sX(ind) - X0(ind)) < 0.0001);
}
};
ctx.finalize();
}

View File

@@ -1,91 +0,0 @@
//===----------------------------------------------------------------------===//
//
// Part of CUDASTF in CUDA C++ Core Libraries,
// under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES.
//
//===----------------------------------------------------------------------===//
#include <cuda/experimental/__stf/stream/stream_ctx.cuh>
#include <cuda/experimental/__stf/utility/dimensions.cuh>
using namespace cuda::experimental::stf;
int main()
{
stream_ctx ctx;
const size_t N = 16;
const size_t M = 16;
/*
* First test an explicit shape by only specifying its size
*/
std::vector<double> A(M * N);
auto lA = ctx.logical_data(make_slice(&A[0], std::tuple<size_t, size_t>{M, N}, M));
ctx.parallel_for(lA.shape(), lA.write())->*[=] _CCCL_DEVICE(size_t i, size_t j, auto sA) {
sA(i, j) = 42.0;
};
// Create a subset of a limited size
box subset_shape(3, 4);
ctx.parallel_for(subset_shape, lA.rw())->*[=] _CCCL_DEVICE(size_t i, size_t j, auto sA) {
sA(i, j) = 13.0;
};
bool checkedA = false;
ctx.host_launch(lA.rw())->*[&checkedA](auto sA) {
for (size_t j = 0; j < sA.extent(1); j++)
{
for (size_t i = 0; i < sA.extent(0); i++)
{
double expected = (i < 3 && j < 4) ? 13.0 : 42.0;
if (sA(i, j) != expected)
{
fprintf(stderr, "sA(%zu,%zu) = %lf, expected %lf\n", i, j, sA(i, j), expected);
}
}
}
checkedA = true;
};
std::vector<double> B(M * N);
auto lB = ctx.logical_data(make_slice(&B[0], std::tuple<size_t, size_t>{M, N}, M));
ctx.parallel_for(lB.shape(), lB.write())->*[=] _CCCL_DEVICE(size_t i, size_t j, auto sB) {
sB(i, j) = 42.0;
};
// Create a subset of a limited size
box subset_shape_2({2, 5}, {5, 8});
ctx.parallel_for(subset_shape_2, lB.rw())->*[=] _CCCL_DEVICE(size_t i, size_t j, auto sB) {
sB(i, j) = 13.0;
};
bool checkedB = false;
ctx.host_launch(lB.rw())->*[&checkedB](auto sB) {
for (size_t j = 0; j < sB.extent(1); j++)
{
for (size_t i = 0; i < sB.extent(0); i++)
{
double expected = (2 <= i && i < 5 && 5 <= j && j < 8) ? 13.0 : 42.0;
if (sB(i, j) != expected)
{
fprintf(stderr, "sB(%zu,%zu) = %lf, expected %lf\n", i, j, sB(i, j), expected);
}
}
}
checkedB = true;
};
ctx.finalize();
assert(checkedA);
assert(checkedB);
}

View File

@@ -1,27 +0,0 @@
//===----------------------------------------------------------------------===//
//
// Part of CUDASTF in CUDA C++ Core Libraries,
// under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES.
//
//===----------------------------------------------------------------------===//
#include <cuda/experimental/stf.cuh>
using namespace cuda::experimental::stf;
int main()
{
context ctx;
int nqpoints = 3;
auto ltoken = ctx.token();
ctx.parallel_for(exec_place::host(), box(5), ltoken.read())->*[nqpoints] __host__(size_t) {
_CCCL_ASSERT(nqpoints == 3, "invalid value");
};
ctx.finalize();
}

View File

@@ -1,75 +0,0 @@
//===----------------------------------------------------------------------===//
//
// Part of CUDASTF in CUDA C++ Core Libraries,
// under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES.
//
//===----------------------------------------------------------------------===//
/**
* @file
* @brief This creates a dummy grid of devices (repeating device 0 multiple
* times) to check that parallel_for works on a grid of places.
*/
#include <cuda/experimental/__places/partitions/tiled_partition.cuh>
#include <cuda/experimental/stf.cuh>
using namespace cuda::experimental::stf;
double X0(size_t i)
{
return sin((double) i);
}
double Y0(size_t i)
{
return cos((double) i);
}
int main()
{
context ctx;
const int N = 1024 * 1024 * 32;
double *X, *Y;
X = new double[N];
Y = new double[N];
for (size_t ind = 0; ind < N; ind++)
{
X[ind] = X0(ind);
Y[ind] = Y0(ind);
}
auto handle_X = ctx.logical_data(X, {N});
auto handle_Y = ctx.logical_data(Y, {N});
auto where = exec_place::repeat(exec_place::current_device(), 8);
double alpha = 3.14;
size_t NITER = 5;
/* Compute Y = Y + alpha X */
for (size_t k = 0; k < NITER; k++)
{
ctx.parallel_for(tiled_partition<1024 * 1024>(), where, handle_X.shape(), handle_X.read(), handle_Y.rw())
->*[=] _CCCL_DEVICE(size_t i, auto sX, auto sY) {
sY(i) += alpha * sX(i);
};
}
ctx.finalize();
for (size_t ind = 0; ind < N; ind++)
{
// Y should be Y0 + NITER alpha X0
assert(fabs(Y[ind] - (Y0(ind) + NITER * alpha * X0(ind))) < 0.0001);
// X should be X0
assert(fabs(X[ind] - X0(ind)) < 0.0001);
}
}

View File

@@ -1,74 +0,0 @@
//===----------------------------------------------------------------------===//
//
// Part of CUDASTF in CUDA C++ Core Libraries,
// under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES.
//
//===----------------------------------------------------------------------===//
/**
* @file
* @brief Check that parallel_for constructs do update slices with shapes of different dimensions
*/
#include <cuda/experimental/stf.cuh>
using namespace cuda::experimental::stf;
__host__ __device__ double x0(size_t i, size_t j)
{
return sin((double) (i - j));
}
__host__ __device__ double y0(size_t i, size_t j)
{
return cos((double) (i + j));
}
int main()
{
context ctx;
const size_t N = 16;
double X[2 * N * 2 * N];
double Y[N * N];
auto lx = ctx.logical_data(make_slice(&X[0], std::tuple{2 * N, 2 * N}, 2 * N));
auto ly = ctx.logical_data(make_slice(&Y[0], std::tuple{N, N}, N));
ctx.parallel_for(lx.shape(), lx.write())->*[=] _CCCL_DEVICE(size_t i, size_t j, auto sx) {
sx(i, j) = x0(i, j);
};
ctx.parallel_for(ly.shape(), lx.read(), ly.write())->*[=] _CCCL_DEVICE(size_t i, size_t j, auto sx, auto sy) {
sy(i, j) = y0(i, j);
for (size_t ii = 0; ii < 2; ii++)
{
for (size_t jj = 0; jj < 2; jj++)
{
sy(i, j) += sx(2 * i + ii, 2 * j + jj);
}
}
};
ctx.parallel_for(exec_place::host(), ly.shape(), ly.read())
->*[=] __host__(size_t i, size_t j, slice<const double, 2> sy) {
double expected = y0(i, j);
for (size_t ii = 0; ii < 2; ii++)
{
for (size_t jj = 0; jj < 2; jj++)
{
expected += x0(2 * i + ii, 2 * j + jj);
}
}
if (fabs(sy(i, j) - expected) > 0.001)
{
printf("sy(%zu, %zu) %f expect %f\n", i, j, sy(i, j), expected);
}
// assert(fabs(sy(i, j) - expected) < 0.001);
};
ctx.finalize();
}

View File

@@ -1,84 +0,0 @@
//===----------------------------------------------------------------------===//
//
// Part of CUDASTF in CUDA C++ Core Libraries,
// under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES.
//
//===----------------------------------------------------------------------===//
/**
* @file
* @brief Apply partitioning operations on shapes to manipulate data subsets
*/
#include <cuda/experimental/__places/partitions/tiled_partition.cuh>
#include <cuda/experimental/__stf/stream/stream_ctx.cuh>
using namespace cuda::experimental::stf;
// Compute which part ID has the item at position "index"
__host__ __device__ size_t ref_tiling(size_t index, size_t tile_size, size_t nparts)
{
// in which tile is this ?
size_t tile_id = index / tile_size;
// part which owns this tile
return (tile_id % nparts);
}
int main()
{
stream_ctx ctx;
const size_t nparts = 4;
const size_t tile_size = 8;
// Be sure to pick a number that is not a divisor to stress the tiling operator
const size_t N = nparts * 3 * tile_size + 7;
double Y[N];
auto ly = ctx.logical_data(Y);
// Init Y
ctx.parallel_for(ly.shape(), ly.write())->*[=] _CCCL_DEVICE(size_t pos, auto sy) {
sy(pos) = -1.0;
};
/*
* We apply a tiling operator on the shape of ly, to work on subsets of ly.
* For each subset, we put the id of the subset in the corresponding
* entries of Y
*
* Note that these tasks are serialized as they perform a rw() on the
* logical data as a whole.
*/
for (size_t part_id = 0; part_id < nparts; part_id++)
{
ctx.parallel_for(tiled<tile_size>(ly.shape(), part_id, nparts), ly.rw())->*[=] _CCCL_DEVICE(size_t pos, auto sy) {
sy(pos) = (double) part_id;
};
}
bool checked = false;
bool* pchecked = &checked;
/* Check the result on the host */
ctx.parallel_for(exec_place::host(), ly.shape(), ly.read())->*[=](size_t pos, slice<const double> sy) {
int expected = static_cast<int>(ref_tiling(pos, tile_size, nparts));
int value = (int) sy(pos);
if (expected != value)
{
printf("POS %zu -> %d (expected %d)\n", pos, value, expected);
}
assert(expected == value);
*pchecked = true;
};
ctx.finalize();
// Ensure verification code did occur
assert(checked);
}