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
190 lines
5.8 KiB
Plaintext
190 lines
5.8 KiB
Plaintext
#include "hip/hip_runtime.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
#define BLOCKDIM 64
|
|
|
|
|
|
/* Macro for checking GPU API return values */
|
|
#define HIP_ASSERT(call) \
|
|
do{ \
|
|
hipError_t gpuErr = call; \
|
|
if(hipSuccess != gpuErr){ \
|
|
printf("GPU API Error - %s:%d: '%s'\n", __FILE__, __LINE__, hipGetErrorString(gpuErr)); \
|
|
exit(1); \
|
|
} \
|
|
}while(0)
|
|
|
|
|
|
// HIP kernel. Each thread takes care of one element of input
|
|
__global__ void cube(double *input, double *output,int offset, int elements_per_stream)
|
|
{
|
|
size_t tid = blockIdx.x*blockDim.x+threadIdx.x;
|
|
size_t gstride = blockDim.x * gridDim.x;
|
|
|
|
// Span all elements assigned to this stream
|
|
for (size_t id = tid + offset; id < offset + elements_per_stream; id += gstride)
|
|
for (size_t i = 0; i < 1000; ++i)
|
|
output[id] = input[id]*input[id]*input[id];
|
|
}
|
|
|
|
void usage()
|
|
{
|
|
printf("Usage: ./compute-comm-overlap <nstreams> <blockSize (optional, default=64)>\n");
|
|
exit(1);
|
|
return;
|
|
}
|
|
|
|
int main( int argc, char* argv[] )
|
|
{
|
|
// Read input arg
|
|
if (argc < 2)
|
|
usage();
|
|
int num_streams = atoi(argv[1]);
|
|
|
|
// Number of threads in each thread block
|
|
int blockSize = BLOCKDIM;
|
|
if (argc == 3)
|
|
blockSize = atoi(argv[2]);
|
|
|
|
// Size of vectors
|
|
int n = 100000000;
|
|
int elements_per_stream = (n % num_streams == 0) ? n/num_streams : -1;
|
|
if (elements_per_stream == -1) {
|
|
printf("ERROR: input value of num_streams does not evenly devide the array size \n");
|
|
printf("Please provide an input value for num_streams that evenly divides %d\n", n);
|
|
exit(1);
|
|
}
|
|
int bytes_per_stream = elements_per_stream*sizeof(double);
|
|
printf("bytes/stream: %f (MB)\n", bytes_per_stream*1.e-6);
|
|
|
|
|
|
// Host input vectors
|
|
double *h_input1;
|
|
//Host output vector
|
|
double *h_output1;
|
|
//Host output vector for verification
|
|
double *h_verify1;
|
|
|
|
// Device input vectors
|
|
double *d_input1;
|
|
//Device output vector
|
|
double *d_output1;
|
|
|
|
//Creating events for timers
|
|
hipEvent_t start, stop;
|
|
hipEventCreate(&start);
|
|
hipEventCreate(&stop);
|
|
|
|
//Creating streams
|
|
|
|
hipStream_t streams[num_streams];
|
|
for (int i = 0; i < num_streams; ++i)
|
|
{
|
|
HIP_ASSERT(hipStreamCreate(&streams[i]));
|
|
}
|
|
|
|
|
|
// Size, in bytes, of each vector
|
|
size_t bytes = n*sizeof(double);
|
|
|
|
// Allocate page locked memory for these vectors on host
|
|
HIP_ASSERT(hipHostMalloc(&h_input1, bytes));
|
|
HIP_ASSERT(hipHostMalloc(&h_output1, bytes));
|
|
|
|
|
|
h_verify1 = (double*)malloc(bytes);
|
|
|
|
|
|
printf("Finished allocating vectors on the CPU\n");
|
|
// Allocate memory for each vector on GPU
|
|
HIP_ASSERT(hipMalloc(&d_input1, bytes));
|
|
HIP_ASSERT(hipMalloc(&d_output1, bytes));
|
|
|
|
printf("Finished allocating vectors on the GPU\n");
|
|
|
|
int i;
|
|
// Initialize vectors on host
|
|
for( i = 0; i < n; i++ ) {
|
|
h_input1[i] = sin(i);
|
|
}
|
|
|
|
// Number of thread blocks in grid
|
|
#ifdef MI300A_RUN
|
|
int gridSizePerStream = 228; //(int)ceil((float)elements_per_stream/blockSize);
|
|
#else
|
|
int gridSizePerStream = 104; //(int)ceil((float)elements_per_stream/blockSize);
|
|
#endif
|
|
printf("gridSizePerStream: %d\n", gridSizePerStream);
|
|
|
|
hipEventRecord(start);
|
|
// Copy and execute in loop
|
|
|
|
#define SPLIT_DATACOPY_KERNEL_CALLS
|
|
#ifndef SPLIT_DATACOPY_KERNEL_CALLS
|
|
for(int i = 0; i < num_streams; i++)
|
|
{
|
|
int offset = i * elements_per_stream;
|
|
HIP_ASSERT(hipMemcpyAsync(&d_input1[offset],&h_input1[offset],bytes_per_stream,hipMemcpyHostToDevice,streams[i]));
|
|
cube<<<gridSizePerStream,blockSize,0,streams[i]>>>(d_input1,d_output1,offset, elements_per_stream);
|
|
HIP_ASSERT(hipMemcpyAsync(&h_output1[offset],&d_output1[offset], bytes_per_stream, hipMemcpyDeviceToHost,streams[i]));
|
|
}
|
|
#else
|
|
// split H2D copies and kernel calls into separate loops
|
|
for(int i = 0; i < num_streams; i++)
|
|
{
|
|
int offset = i * elements_per_stream;
|
|
HIP_ASSERT(hipMemcpyAsync(&d_input1[offset],&h_input1[offset],bytes_per_stream,hipMemcpyHostToDevice,streams[i]));
|
|
}
|
|
for(int i = 0; i < num_streams; i++)
|
|
{
|
|
int offset = i * elements_per_stream;
|
|
cube<<<gridSizePerStream,blockSize,0,streams[i]>>>(d_input1,d_output1,offset, elements_per_stream);
|
|
}
|
|
for(int i = 0; i < num_streams; i++)
|
|
{
|
|
int offset = i * elements_per_stream;
|
|
HIP_ASSERT(hipMemcpyAsync(&h_output1[offset],&d_output1[offset], bytes_per_stream, hipMemcpyDeviceToHost,streams[i]));
|
|
}
|
|
#endif //SPLIT_DATACOPY_KERNEL_CALLS
|
|
|
|
hipEventRecord(stop);
|
|
hipEventSynchronize(stop);
|
|
|
|
float milliseconds = 0;
|
|
hipEventElapsedTime(&milliseconds, start, stop);
|
|
printf("Time required total (ms) %f\n", milliseconds);
|
|
printf("Finished copying the output vector from the GPU to the CPU\n");
|
|
|
|
//Compute for CPU
|
|
for(i=0; i <n; i++)
|
|
{
|
|
h_verify1[i] = h_input1[i] * h_input1[i] * h_input1[i];
|
|
}
|
|
|
|
|
|
//Verfiy results
|
|
for(i=0; i <n; i++)
|
|
{
|
|
if (abs(h_verify1[i] - h_output1[i]) > 1e-5)
|
|
{
|
|
printf("Error at position i %d, Expected: %f, Found: %f \n", i, h_verify1[i], h_output1[i]);
|
|
}
|
|
}
|
|
|
|
printf("Releasing GPU memory\n");
|
|
|
|
// Release device memory
|
|
HIP_ASSERT(hipFree(d_input1));
|
|
HIP_ASSERT(hipFree(d_output1));
|
|
|
|
// Release host memory
|
|
printf("Releasing CPU memory\n");
|
|
HIP_ASSERT(hipHostFree(h_input1));
|
|
HIP_ASSERT(hipHostFree(h_output1));
|
|
free(h_verify1);
|
|
|
|
return 0;
|
|
}
|