Files
TheRock/rocm-systems/projects/hipfile/test/legacy/test-hipfile-batch.cpp
T
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

357 lines
13 KiB
C++

/* Copyright (c) Advanced Micro Devices, Inc. All rights reserved.
*
* SPDX-License-Identifier: MIT
*/
/* Test hipFile batch operations
*
* This is a temporary test until we get proper testing
* set up.
*/
#include "hipfile.h"
#include "hipfile-warnings.h"
#include <hip/hip_runtime_api.h>
#include <cerrno>
#include <cstdarg>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#define MAX_BATCH_IO_OPS 16
#define MAX_BUFFER_SIZE 4096
#define LOG_DEBUG 1
// Not fixing this already buggy piece of test software.
HIPFILE_WARN_FORMAT_NONLITERAL_OFF
void static debug_printf(const char *format, ...)
{
#if LOG_DEBUG
va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);
#endif
}
HIPFILE_WARN_FORMAT_NONLITERAL_ON
int
main(int argc, char *argv[])
{
void *dbufs[MAX_BATCH_IO_OPS];
hipFileHandle_t fh[MAX_BATCH_IO_OPS];
hipFileDescr_t fd[MAX_BATCH_IO_OPS];
hipFileIOParams_t batch_params[MAX_BATCH_IO_OPS];
hipFileIOEvents_t batch_events[MAX_BATCH_IO_OPS];
hipFileBatchHandle_t batch_handle;
hipFileError_t err;
hipError_t hip_err;
unsigned batch_flags = 0;
unsigned batch_size;
int input_batch_size;
const char *fin_path;
const char *fout_path;
struct stat fstat;
int rc = 0;
unsigned events_completed = 0;
if (argc != 4) {
fprintf(stderr, "Usage: %s FILE_IN FILE_OUT BATCH_SIZE\n", argv[0]);
exit(1);
}
fin_path = argv[1];
if (stat(fin_path, &fstat)) {
fprintf(stderr, "Could not stat %s: %s\n", fin_path, strerror(errno));
return 1;
}
fout_path = argv[2];
input_batch_size = atoi(argv[3]);
if (input_batch_size <= 0 || input_batch_size > MAX_BATCH_IO_OPS) {
fprintf(stderr, "batch_size must be in the range [1,%d], not %d.\n", MAX_BATCH_IO_OPS,
input_batch_size);
return 1;
}
batch_size = static_cast<unsigned>(input_batch_size);
// Initialize Data Structs to make cleanup more reliable.
memset(dbufs, 0, MAX_BATCH_IO_OPS * sizeof(void *));
memset(fh, 0, MAX_BATCH_IO_OPS * sizeof(hipFileHandle_t));
memset(fd, 0, MAX_BATCH_IO_OPS * sizeof(hipFileDescr_t));
memset(batch_params, 0, MAX_BATCH_IO_OPS * sizeof(hipFileIOParams_t));
memset(batch_events, 0, MAX_BATCH_IO_OPS * sizeof(hipFileIOEvents_t));
for (unsigned i = 0; i < batch_size; i++) {
fd[i].handle.fd = -1;
}
// Allocate buffers for GPU IO
for (unsigned i = 0; i < batch_size; i++) {
debug_printf("hipMalloc %d\n", i);
hip_err = hipMalloc(&dbufs[i], MAX_BUFFER_SIZE);
if (hip_err != hipSuccess) {
fprintf(stderr, "Could not allocate buffer: %d.\n", hip_err);
return 1;
}
hip_err = hipMemset(dbufs[i], 0, MAX_BUFFER_SIZE);
if (hip_err != hipSuccess) {
fprintf(stderr, "Could not zero-out buffer: %d\n", hip_err);
rc = 1;
goto free_dbufs;
}
debug_printf("hipFileBufRegister %d\n", i);
err = hipFileBufRegister(dbufs[i], MAX_BUFFER_SIZE, 0);
if (err.err != hipFileSuccess) {
fprintf(stderr, "Failed to register GPU buffer.\n");
fprintf(stderr, "hipFileError: %d\n", err.err);
fprintf(stderr, "hipError: %d\n", err.hip_drv_err);
rc = 1;
goto free_dbufs;
}
}
debug_printf("hipFileDriverOpen\n");
err = hipFileDriverOpen();
if (err.err != hipFileSuccess) {
fprintf(stderr, "Failed to open GPU IO Driver.\n");
fprintf(stderr, "hipFileError: %d\n", err.err);
fprintf(stderr, "hipError: %d\n", err.hip_drv_err);
rc = 1;
goto free_dbufs;
}
// Setup Batch FD's.
for (unsigned i = 0; i < batch_size; i++) {
debug_printf("open %d\n", i);
fd[i].handle.fd = open(fin_path, O_RDONLY | O_DIRECT);
if (fd[i].handle.fd < 0) {
fprintf(stderr, "Could not open %s: %s\n", fin_path, strerror(errno));
rc = 1;
goto close_files;
}
fd[i].type = hipFileHandleTypeOpaqueFD;
debug_printf("hipFileHandleRegister %d\n", i);
err = hipFileHandleRegister(&fh[i], &fd[i]);
if (err.err != hipFileSuccess) {
fprintf(stderr, "Failed to register fd[%u].\n", i);
fprintf(stderr, "hipFileError: %d\n", err.err);
fprintf(stderr, "hipError: %d\n", err.hip_drv_err);
rc = 1;
goto close_files;
}
// Setup the Batch IO Params to first read from the file.
batch_params[i].mode = hipFileBatch;
batch_params[i].fh = fh[i];
batch_params[i].u.batch.devPtr_base = dbufs[i];
batch_params[i].u.batch.file_offset = i * 16;
batch_params[i].u.batch.devPtr_offset = 0;
batch_params[i].u.batch.size = 16;
batch_params[i].opcode = hipFileBatchRead;
batch_params[i].cookie = &batch_params[i];
}
// Setup and Execute our Batch Read operation.
debug_printf("hipFileBatchIOSetup\n");
err = hipFileBatchIOSetUp(&batch_handle, batch_size);
if (err.err != hipFileSuccess) {
fprintf(stderr, "Failed to setup Read Batch IO.\n");
fprintf(stderr, "hipFileError: %d\n", err.err);
fprintf(stderr, "hipError: %d\n", err.hip_drv_err);
rc = 1;
goto close_files;
}
debug_printf("hipFileBatchIOSubmit\n");
err = hipFileBatchIOSubmit(batch_handle, batch_size, batch_params, batch_flags);
if (err.err != hipFileSuccess) {
fprintf(stderr, "Failed to submit Read Batch IO.\n");
fprintf(stderr, "hipFileError: %d\n", err.err);
fprintf(stderr, "hipError: %d\n", err.hip_drv_err);
rc = 1;
goto close_files;
}
// Get Batch Events to confirm data read successfully.
events_completed = 0;
while (events_completed != batch_size) {
memset(batch_events, 0, MAX_BATCH_IO_OPS * sizeof(hipFileIOEvents_t));
unsigned num_events_reported = batch_size;
err = hipFileBatchIOGetStatus(batch_handle, batch_size, &num_events_reported, batch_events, nullptr);
if (err.err != hipFileSuccess) {
fprintf(stderr, "Failed to fetch Read Batch IO status.\n");
fprintf(stderr, "hipFileError: %d\n", err.err);
fprintf(stderr, "hipError: %d\n", err.hip_drv_err);
goto finish_batch_io;
}
debug_printf("Received %d Batch IO Events.\n", num_events_reported);
events_completed += num_events_reported;
for (unsigned i = 0; i < num_events_reported; i++) {
// At this point the example copies the data into a Host buffer.
// For this, we are just going to perform a nominal check on the
// members within hipFileIOEvents_t.
hipFileIOEvents_t event = batch_events[i];
fprintf(stderr, "hipFileIOEvent #%u\n", i);
fprintf(stderr, "Status: %d -- Return Value: %zu\n", event.status, event.ret);
fprintf(stderr, "Cookie: %p\n", event.cookie);
bool match = (event.cookie == &batch_params[i]);
fprintf(stderr, "Cookie ?= hipFileIOParams: %p ?= %p : %s\n", event.cookie,
reinterpret_cast<void *>(&batch_params[i]), match ? "true" : "false");
}
}
hipFileBatchIODestroy(batch_handle);
// Ideally we can write-back the data here to an output file.
// Setup Write Batch FD's.
// Setup Write Batch FD's.
// We are reusing our previous data structures. So we will free and
// reinitialize for the write step.
for (unsigned i = 0; i < batch_size; i++) {
debug_printf("hipFileHandleDeregister %d\n", i);
hipFileHandleDeregister(fh[i]);
debug_printf("close %d\n", i);
close(fd[i].handle.fd);
debug_printf("open output file %d\n", i);
fd[i].handle.fd = open(fout_path, O_RDWR | O_CREAT | O_DIRECT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (fd[i].handle.fd < 0) {
fprintf(stderr, "Could not open %s: %s\n", fout_path, strerror(errno));
rc = 1;
goto close_files;
}
fd[i].type = hipFileHandleTypeOpaqueFD;
debug_printf("hipFileHandleRegister %d\n", i);
err = hipFileHandleRegister(&fh[i], &fd[i]);
if (err.err != hipFileSuccess) {
fprintf(stderr, "Failed to register fd[%u].\n", i);
fprintf(stderr, "hipFileError: %d\n", err.err);
fprintf(stderr, "hipError: %d\n", err.hip_drv_err);
rc = 1;
goto close_files;
}
// Setup the Batch IO Params to write to the file.
batch_params[i].mode = hipFileBatch;
batch_params[i].fh = fh[i];
batch_params[i].u.batch.devPtr_base = dbufs[i];
batch_params[i].u.batch.file_offset = i * 16;
batch_params[i].u.batch.devPtr_offset = 0;
batch_params[i].u.batch.size = 16;
batch_params[i].opcode = hipFileBatchWrite;
}
// Setup and Execute our Batch Write operation.
debug_printf("hipFileBatchIOSetup\n");
err = hipFileBatchIOSetUp(&batch_handle, batch_size);
if (err.err != hipFileSuccess) {
fprintf(stderr, "Failed to setup Write Batch IO.\n");
fprintf(stderr, "hipFileError: %d\n", err.err);
fprintf(stderr, "hipError: %d\n", err.hip_drv_err);
rc = 1;
goto close_files;
}
debug_printf("hipFileBatchIOSubmit\n");
err = hipFileBatchIOSubmit(batch_handle, batch_size, batch_params, batch_flags);
if (err.err != hipFileSuccess) {
fprintf(stderr, "Failed to submit Write Batch IO.\n");
fprintf(stderr, "hipFileError: %d\n", err.err);
fprintf(stderr, "hipError: %d\n", err.hip_drv_err);
rc = 1;
goto close_files;
}
// Get Batch Events to confirm data read successfully.
events_completed = 0;
while (events_completed != batch_size) {
memset(batch_events, 0, MAX_BATCH_IO_OPS * sizeof(hipFileIOEvents_t));
unsigned num_events_reported = batch_size;
err = hipFileBatchIOGetStatus(batch_handle, batch_size, &num_events_reported, batch_events, nullptr);
if (err.err != hipFileSuccess) {
fprintf(stderr, "Failed to fetch Write Batch IO status.\n");
fprintf(stderr, "hipFileError: %d\n", err.err);
fprintf(stderr, "hipError: %d\n", err.hip_drv_err);
goto finish_batch_io;
}
debug_printf("Received %d Batch IO Events.\n", num_events_reported);
events_completed += num_events_reported;
for (unsigned i = 0; i < num_events_reported; i++) {
// At this point the example copies the data into a Host buffer.
// For this, we are just going to perform a nominal check on the
// members within hipFileIOEvents_t.
hipFileIOEvents_t event = batch_events[i];
fprintf(stderr, "hipFileIOEvent #%u\n", i);
fprintf(stderr, "Status: %d -- Return Value: %zu\n", event.status, event.ret);
}
}
finish_batch_io:
// Only needs to be run if hipFileBatchIOSubmit was successful.
debug_printf("hipFileBatchIODestroy\n");
hipFileBatchIODestroy(batch_handle);
close_files:
for (unsigned i = 0; i < batch_size; i++) {
if (fd[i].handle.fd >= 0) {
if (fh[i] != nullptr) {
debug_printf("hipFileHandleDeregister %u\n", i);
hipFileHandleDeregister(fh[i]);
if (err.err != hipFileSuccess) {
fprintf(stderr, "Failed to deregister fd[%u].\n", i);
fprintf(stderr, "hipFileError: %d\n", err.err);
fprintf(stderr, "hipError: %d\n", err.hip_drv_err);
rc = 1;
}
}
debug_printf("close %d\n", i);
int close_status = close(fd[i].handle.fd);
if (close_status) {
fprintf(stderr, "Failed to close fd[%u]: %s\n", i, strerror(errno));
rc = 1;
}
}
}
debug_printf("hipFileDriverClose\n");
err = hipFileDriverClose();
if (err.err != hipFileSuccess) {
fprintf(stderr, "Failed to close GPU IO Driver.\n");
fprintf(stderr, "hipFileError: %d\n", err.err);
fprintf(stderr, "hipError: %d\n", err.hip_drv_err);
rc = 1;
}
free_dbufs:
for (unsigned i = 0; i < batch_size; i++) {
debug_printf("hipFileBufDeregister %u\n", i);
err = hipFileBufDeregister(dbufs[i]);
if (err.err != hipFileSuccess) {
fprintf(stderr, "Failed to deregister GPU buffer %u.\n", i);
fprintf(stderr, "hipFileError: %d\n", err.err);
fprintf(stderr, "hipError: %d\n", err.hip_drv_err);
rc = 1;
}
if (dbufs[i] != nullptr) {
debug_printf("hipFree %u\n", i);
hip_err = hipFree(dbufs[i]);
if (hip_err != hipSuccess) {
fprintf(stderr, "Could not free device buffer %u\n", i);
rc = 1;
}
}
}
return rc;
}