Files
project_6/cccl_upstream/cudax/test/copy/copy.cu
muh-bot dedf08166a [CCCL] Add missing CCCL components: c2h, nvbench_helper, cmake, cudax, AGENTS.md
Added 863 files from NVIDIA/cccl sparse checkout:
- c2h/ (27 files): Catch2 test helpers — generators, validators, runner
- nvbench_helper/ (10 files): Benchmark harness utilities
- cmake/ (29 files): CMake presets and build helpers
- cudax/ (794 files): Experimental CUDA extensions
- AGENTS.md: NVIDIA's official AI agent instructions for CCCL
- CMakePresets.json: Standardized build configurations
- cccl-version.json: Version tracking

Also added CCCL_ASSET_MAP.md mapping all 4295 CCCL files to
competition value and PRD items.

cccl_upstream now covers 100% of competition-critical assets:
- 27 tuning headers (SM80/90/100 benchmark data)
- 32 dispatch headers (algorithm implementations)
- 60 Thrust examples (correctness verification)
- 217 CUB Catch2 tests (regression matrix)
- 153 CUB benchmarks (parameter space search)
- 18 CUB examples (API verification)
- 27 test helpers + benchmark harness
- 794 cudax experimental extensions
2026-08-06 02:14:18 +00:00

340 lines
11 KiB
Plaintext

//===----------------------------------------------------------------------===//
//
// Part of CUDA Experimental 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) 2026 NVIDIA CORPORATION & AFFILIATES.
//
//===----------------------------------------------------------------------===//
#include <thrust/host_vector.h>
#include <cuda/std/array>
#include "copy_common.cuh"
/***********************************************************************************************************************
* 1D Tests
**********************************************************************************************************************/
// src: (16):(1)
// dst: (16):(1)
TEST_CASE("copy d2d 1D", "[copy][d2d][1d]")
{
constexpr int N = 16;
test_copy<layout_right>(make_iota<int>(N), N);
}
/***********************************************************************************************************************
* 2D Tests
**********************************************************************************************************************/
// src: (4,8):(8,1)
// dst: (4,8):(8,1)
TEST_CASE("copy d2d 2D row-major to row-major", "[copy][d2d][2d][basic]")
{
constexpr int M = 4;
constexpr int N = 8;
test_copy<layout_right>(make_iota<int>(M * N), M, N);
}
// src: (4,8):(1,4)
// dst: (4,8):(1,4)
TEST_CASE("copy d2d 2D column-major to column-major", "[copy][d2d][2d][basic]")
{
constexpr int M = 4;
constexpr int N = 8;
test_copy<layout_left>(make_iota<int>(M * N), M, N);
}
// src: (4,8):(8,1)
// dst: (4,8):(1,4)
TEST_CASE("copy d2d 2D row-major to column-major", "[copy][d2d][2d][basic]")
{
constexpr int M = 4;
constexpr int N = 8;
auto data = make_iota<int>(M * N);
thrust::host_vector<int> expected(M * N);
for (int i = 0; i < M; ++i)
{
for (int j = 0; j < N; ++j)
{
expected[i + static_cast<std::size_t>(j) * M] = static_cast<int>(static_cast<std::size_t>(i) * N + j);
}
}
test_copy<layout_right, layout_left>(data, expected, M, N);
}
// src: (4,8):(1,4)
// dst: (4,8):(8,1)
TEST_CASE("copy d2d 2D column-major to row-major", "[copy][d2d][2d][basic]")
{
constexpr int M = 4;
constexpr int N = 8;
auto data = make_iota<int>(M * N);
thrust::host_vector<int> expected(M * N);
for (int i = 0; i < M; ++i)
{
for (int j = 0; j < N; ++j)
{
expected[static_cast<std::size_t>(i) * N + j] = static_cast<int>(i + static_cast<std::size_t>(j) * M);
}
}
test_copy<layout_left, layout_right>(data, expected, M, N);
}
// src: (1280,2564):(2564,1)
// dst: (1280,2564):(2564,1)
TEST_CASE("copy d2d 2D large", "[copy][d2d][2d][large]")
{
constexpr int M = 1280;
constexpr int N = 2564;
test_copy<layout_right>(make_iota<int>(M * N), M, N);
}
/***********************************************************************************************************************
* 3D Tests
**********************************************************************************************************************/
// src: (2,3,4):(12,4,1)
// dst: (2,3,4):(12,4,1)
TEST_CASE("copy d2d 3D row-major", "[copy][d2d][3d]")
{
constexpr int D0 = 2;
constexpr int D1 = 3;
constexpr int D2 = 4;
test_copy<layout_right>(make_iota<int>(D0 * D1 * D2), D0, D1, D2);
}
// src: (2,3,4):(12,4,1)
// dst: (2,3,4):(1,2,6)
TEST_CASE("copy d2d 3D row-major to column-major", "[copy][d2d][3d]")
{
constexpr int D0 = 2;
constexpr int D1 = 3;
constexpr int D2 = 4;
constexpr int total = D0 * D1 * D2;
auto data = make_iota<int>(total);
thrust::host_vector<int> expected(total);
for (int i = 0; i < D0; ++i)
{
for (int j = 0; j < D1; ++j)
{
for (int k = 0; k < D2; ++k)
{
expected[i + static_cast<std::size_t>(j) * D0 + static_cast<std::size_t>(k) * D0 * D1] =
static_cast<int>(static_cast<std::size_t>(i) * (D1 * D2) + static_cast<std::size_t>(j) * D2 + k);
}
}
}
test_copy<layout_right, layout_left>(data, expected, D0, D1, D2);
}
/***********************************************************************************************************************
* Strided Layout Tests
**********************************************************************************************************************/
// src: (4,8):(16,1)
// dst: (4,8):(16,1)
TEST_CASE("copy d2d 2D strided padded row-major", "[copy][d2d][2d][stride][row]")
{
constexpr int M = 4;
constexpr int N = 8;
constexpr int Ld = 16;
cuda::std::array<int, 2> shape{M, N};
cuda::std::array<int, 2> strides{Ld, 1};
using extents_t = cuda::std::dextents<int, 2>;
using mapping_t = cuda::std::layout_stride::mapping<extents_t>;
const auto span_size = static_cast<int>(mapping_t(extents_t(shape), strides).required_span_size());
thrust::host_vector<int> data(span_size, 0);
for (int i = 0; i < M; ++i)
{
for (int j = 0; j < N; ++j)
{
data[static_cast<std::size_t>(i) * Ld + j] = static_cast<int>(static_cast<std::size_t>(i) * N + j);
}
}
test_copy_strided(data, shape, strides);
}
// src: (4,8):(1,16)
// dst: (4,8):(1,16)
TEST_CASE("copy d2d 2D strided padded column-major", "[copy][d2d][2d][stride][column]")
{
constexpr int M = 4;
constexpr int N = 8;
constexpr int Ld = 16;
cuda::std::array<int, 2> shape{M, N};
cuda::std::array<int, 2> strides{1, Ld};
using extents_t = cuda::std::dextents<int, 2>;
using mapping_t = cuda::std::layout_stride::mapping<extents_t>;
const auto span_size = static_cast<int>(mapping_t(extents_t(shape), strides).required_span_size());
thrust::host_vector<int> data(span_size, 0);
for (int i = 0; i < M; ++i)
{
for (int j = 0; j < N; ++j)
{
data[i + static_cast<std::size_t>(j) * Ld] = static_cast<int>(static_cast<std::size_t>(i) * N + j);
}
}
test_copy_strided(data, shape, strides);
}
// src: (2,3,4):(12,4,1)
// dst: (2,3,4):(1,8,2)
TEST_CASE("copy d2d 3D strided permutation", "[copy][d2d][3d][stride][permutation]")
{
constexpr int D0 = 2;
constexpr int D1 = 3;
constexpr int D2 = 4;
auto input = make_iota<int>(D0 * D1 * D2);
cuda::std::array<int, 3> shape{D0, D1, D2};
cuda::std::array<int, 3> src_strides{D1 * D2, D2, 1};
cuda::std::array<int, 3> dst_strides{1, D2 * D0, D0};
using extents_t = cuda::std::dextents<int, 3>;
using mapping_t = cuda::std::layout_stride::mapping<extents_t>;
const auto dst_span = static_cast<int>(mapping_t(extents_t(shape), dst_strides).required_span_size());
thrust::host_vector<int> expected(dst_span, 0);
for (int i = 0; i < D0; ++i)
{
for (int j = 0; j < D1; ++j)
{
for (int k = 0; k < D2; ++k)
{
expected[i + static_cast<std::size_t>(j) * (D2 * D0) + static_cast<std::size_t>(k) * D0] =
input[static_cast<std::size_t>(i) * (D1 * D2) + static_cast<std::size_t>(j) * D2 + k];
}
}
}
test_copy_strided(input, expected, shape, src_strides, dst_strides);
}
// src: (2,3,4):(12,4,1)
// dst: (2,3,4):(8,16,1)
TEST_CASE("copy d2d 3D strided different stride order", "[copy][d2d][3d][stride][tile]")
{
constexpr int D0 = 2;
constexpr int D1 = 3;
constexpr int D2 = 4;
auto input = make_iota<int>(D0 * D1 * D2);
cuda::std::array<int, 3> shape{D0, D1, D2};
cuda::std::array<int, 3> src_strides{D1 * D2, D2, 1};
cuda::std::array<int, 3> dst_strides{8, 16, 1};
using extents_t = cuda::std::dextents<int, 3>;
using mapping_t = cuda::std::layout_stride::mapping<extents_t>;
const auto dst_span = static_cast<int>(mapping_t(extents_t(shape), dst_strides).required_span_size());
thrust::host_vector<int> expected(dst_span, 0);
for (int i = 0; i < D0; ++i)
{
for (int j = 0; j < D1; ++j)
{
for (int k = 0; k < D2; ++k)
{
expected[static_cast<std::size_t>(i) * 8 + static_cast<std::size_t>(j) * 16 + k] =
input[static_cast<std::size_t>(i) * (D1 * D2) + static_cast<std::size_t>(j) * D2 + k];
}
}
}
test_copy_strided(input, expected, shape, src_strides, dst_strides);
}
/***********************************************************************************************************************
* Different Element Types
**********************************************************************************************************************/
// src: (1024):(1)
// dst: (1024):(1)
TEST_CASE("copy d2d 1D double", "[copy][d2d][types][double]")
{
constexpr int N = 1024;
thrust::host_vector<double> data(N);
for (int i = 0; i < N; ++i)
{
data[i] = static_cast<double>(i) * 0.5;
}
test_copy<layout_right>(data, N);
}
// src: (2048):(1)
// dst: (2048):(1)
TEST_CASE("copy d2d 1D short", "[copy][d2d][types][short]")
{
constexpr int N = 2048;
thrust::host_vector<short> data(N);
for (int i = 0; i < N; ++i)
{
data[i] = static_cast<short>(i % 1000);
}
test_copy<layout_right>(data, N);
}
// src: (4096):(1)
// dst: (4096):(1)
TEST_CASE("copy d2d 1D char", "[copy][d2d][types][char]")
{
constexpr int N = 4096;
thrust::host_vector<char> data(N);
for (int i = 0; i < N; ++i)
{
data[i] = static_cast<char>(i % 128);
}
test_copy<layout_right>(data, N);
}
/***********************************************************************************************************************
* Large / Multi-Block Tests
**********************************************************************************************************************/
// src: (100000):(1)
// dst: (100000):(1)
TEST_CASE("copy d2d 1D large", "[copy][d2d][1d][large]")
{
constexpr int N = 100000;
test_copy<layout_right>(make_iota<float>(N), N);
}
// src: (13,17):(17,1)
// dst: (13,17):(1,13)
TEST_CASE("copy d2d 2D transposition non-tile-divisible", "[copy][d2d][2d][boundary]")
{
constexpr int M = 13;
constexpr int N = 17;
auto data = make_iota<float>(M * N);
thrust::host_vector<float> expected(M * N);
for (int r = 0; r < M; ++r)
{
for (int c = 0; c < N; ++c)
{
expected[r + static_cast<std::size_t>(c) * M] = data[static_cast<std::size_t>(r) * N + c];
}
}
test_copy<layout_right, layout_left>(data, expected, M, N);
}
// src: (100,200):(200,1)
// dst: (100,200):(1,100)
TEST_CASE("copy d2d 2D large transposition", "[copy][d2d][2d][large][transpose]")
{
constexpr int M = 100;
constexpr int N = 200;
auto data = make_iota<int>(M * N);
thrust::host_vector<int> expected(M * N);
for (int r = 0; r < M; ++r)
{
for (int c = 0; c < N; ++c)
{
expected[r + static_cast<std::size_t>(c) * M] = data[static_cast<std::size_t>(r) * N + c];
}
}
test_copy<layout_right, layout_left>(data, expected, M, N);
}