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
112 lines
3.9 KiB
Plaintext
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();
|
|
}
|