Files
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

112 lines
3.9 KiB
Plaintext

#include "primbench.hpp"
#include <cuda_runtime.h>
// All benchmarked types must be declared
// This allows you to for example format `long long` as `int64_t`, or `i64`
PRIMBENCH_REGISTER_TYPE(char, "char")
PRIMBENCH_REGISTER_TYPE(long long, "long long")
// Simple copy kernel
template<typename T, unsigned int BlockSize, unsigned int ItemsPerThread>
__global__ __launch_bounds__(BlockSize)
void copy_kernel(const T* input, T* output)
{
unsigned int idx = threadIdx.x + blockIdx.x * BlockSize * ItemsPerThread;
#pragma unroll
for(unsigned int i = 0; i < ItemsPerThread; ++i)
output[idx + i * BlockSize] = input[idx + i * BlockSize];
}
template<typename T>
struct copy_benchmark : public primbench::benchmark_interface
{
primbench::json meta() const override
{
// This meta() method must return an `algo` key
// The `algo` name must be identical across all queued specializations
// primbench::json objects can be nested
return primbench::json{}.add("algo", "copy").add("type", primbench::name<T>());
}
// This contains both the setup and running of the benchmark
void run(primbench::state& state) override
{
const auto& stream = state.stream;
const auto& bytes = state.size;
// primbench::log() calls report progress in gray
// They help with discovering slow setup steps
primbench::log("Calculating items");
size_t N = bytes / sizeof(T);
constexpr unsigned int BlockSize = 256;
constexpr unsigned int ItemsPerThread = 4;
const size_t items_per_block = BlockSize * ItemsPerThread;
const size_t items = items_per_block * ((N + items_per_block - 1) / items_per_block);
primbench::log("Generating input data");
std::vector<T> h_input(items);
for(size_t i = 0; i < items; ++i)
h_input[i] = T(i);
primbench::log("Allocating device memory");
T* d_input;
T* d_output;
PRIMBENCH_CHECK(cudaMalloc(&d_input, items * sizeof(T)));
PRIMBENCH_CHECK(cudaMalloc(&d_output, items * sizeof(T)));
primbench::log("Copying to device");
PRIMBENCH_CHECK(cudaMemcpyAsync(d_input,
h_input.data(),
items * sizeof(T),
cudaMemcpyHostToDevice,
stream));
dim3 grid(items / items_per_block);
dim3 block(BlockSize);
// primbench uses this to calculate the items/sec and bytes/sec
state.set_items(items);
state.add_reads<T>(items);
state.add_writes<T>(items);
// Optional output validation (called once during warmup)
// Disable by defining PRIMBENCH_NO_TEST
state.test(
[&]
{
// Copy part of the output to host for quick validation
std::vector<T> h_output(3);
PRIMBENCH_CHECK(
cudaMemcpy(h_output.data(), d_output, 3 * sizeof(T), cudaMemcpyDeviceToHost));
// Use placeholders (e.g., {0, 0, 0}) if expected
// values are unknown; assertion failures will print
// the actual values for you to copy-paste
PRIMBENCH_ASSERT(h_output, {0, 1, 2});
});
// This passes a lambda to primbench, which calls it many times
// primbench completely handles synchronization
state.run(
[&] {
copy_kernel<T, BlockSize, ItemsPerThread>
<<<grid, block, 0, stream>>>(d_input, d_output);
});
PRIMBENCH_CHECK(cudaFree(d_input));
PRIMBENCH_CHECK(cudaFree(d_output));
}
};
int main(int argc, char* argv[])
{
primbench::executor executor(argc, argv);
executor.queue<copy_benchmark<char>>();
executor.queue<copy_benchmark<long long>>();
executor.run();
}