SWDEV-553436 Created wrapper functions for file read and file write (#935)

Tá an tiomantas seo le fáil i:
Sam Ruscica
2025-10-07 09:42:22 -04:00
tiomanta ag GitHub
tuismitheoir da457c9a43
tiomantas 135c38b41c
D'athraigh 11 comhad le 311 breiseanna agus 8 scriosta
@@ -0,0 +1,68 @@
/* Copyright (c) 2025 Advanced Micro Devices, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. */
#pragma once
#include <hip/hip_runtime.h>
typedef struct hipAmdFileHandle_t {
/*
* file handle for AIS read & write. Linux will use fd.
* pad is keep the size consistent across different platforms.
*/
union {
void* handle;
int fd;
uint8_t pad[8];
};
} hipAmdFileHandle_t;
/**
* @brief Read data from a file to device memory.
*
* Reads data from a file at the specified offset into a device memory buffer.
* The device memory pointer must be accessible from the host and point to
* a valid allocation.
*
* @param[IN] handle: Handle of the file to read from.
* @param[IN] devicePtr: Device memory buffer pointer to store the read data.
* @param[IN] size: Size in bytes of the data to read.
* @param[IN] file_offset: Offset in bytes into the file where data will be read from.
* @param[IN/OUT] size_copied: Actual number of bytes copied.
* @param[IN/OUT] status: Additional status if any.
*/
hipError_t hipAmdFileRead(hipAmdFileHandle_t handle, void* devicePtr, uint64_t size, int64_t file_offset,
uint64_t* size_copied, int32_t* status);
/**
* Write data from device memory to a file.
*
* Writes data from device memory buffer to a file at the specified offset.
* The device memory pointer must be accessible from the host and point to
* a valid allocation.
*
* @param[IN] handle: Handle of the file to write to.
* @param[IN] devicePtr: Device memory buffer pointer containing data to write.
* @param[IN] size: Size in bytes of the data to write.
* @param[IN] file_offset: Offset in bytes into the file where data will be written.
* @param[IN/OUT] size_copied: Actual number of bytes written.
* @param[IN/OUT] status: Additional status if any.
*/
hipError_t hipAmdFileWrite(hipAmdFileHandle_t handle, void* devicePtr, uint64_t size, int64_t file_offset,
uint64_t* size_copied, int32_t* status);
+1
Féach ar an gComhad
@@ -118,6 +118,7 @@ target_sources(amdhip64 PRIVATE
hip_peer.cpp
hip_platform.cpp
hip_profile.cpp
hip_storage.cpp
hip_stream_ops.cpp
hip_stream.cpp
hip_surface.cpp
+15 -2
Féach ar an gComhad
@@ -20,6 +20,7 @@
#include <hip/hip_runtime.h>
#include <hip/hip_deprecated.h>
#include <hip/amd_detail/hip_storage.h>
#include "hip_internal.hpp"
#include "hip_mempool_impl.hpp"
@@ -199,8 +200,7 @@ void Device::WaitActiveStreams(hip::Stream* blocking_stream, bool wait_null_stre
((active_stream->Flags() & hipStreamNonBlocking) == 0) &&
// and it's not the current stream
(active_stream != blocking_stream)) {
ClPrint(amd::LOG_DETAIL_DEBUG, amd::LOG_WAIT, "Waiting on active stream %p",
active_stream);
ClPrint(amd::LOG_DETAIL_DEBUG, amd::LOG_WAIT, "Waiting on active stream %p", active_stream);
// Get the last valid command
waitForStream(active_stream);
}
@@ -771,6 +771,7 @@ hipError_t hipGetProcAddress(const char* symbol, void** pfn, int hipVersion, uin
HIP_INIT_API(hipGetProcAddress, symbol, pfn, hipVersion, flags, symbolStatus);
std::string symbolString = symbol;
if (symbol == nullptr || symbolString == "" || pfn == nullptr) {
HIP_RETURN(hipErrorInvalidValue);
}
@@ -783,6 +784,18 @@ hipError_t hipGetProcAddress(const char* symbol, void** pfn, int hipVersion, uin
if (hipVersion >= 600) {
symbolString = "hipChooseDeviceR0600";
}
} else if (symbolString == "hipAmdFileRead") {
*pfn = reinterpret_cast<void*>(&hipAmdFileRead);
if (symbolStatus != nullptr) {
*symbolStatus = HIP_GET_PROC_ADDRESS_SUCCESS;
}
HIP_RETURN(hipSuccess);
} else if (symbolString == "hipAmdFileWrite") {
*pfn = reinterpret_cast<void*>(&hipAmdFileWrite);
if (symbolStatus != nullptr) {
*symbolStatus = HIP_GET_PROC_ADDRESS_SUCCESS;
}
HIP_RETURN(hipSuccess);
}
void* handle = hip::PlatformState::instance().getDynamicLibraryHandle();
+70
Féach ar an gComhad
@@ -0,0 +1,70 @@
/* Copyright (c) 2025 Advanced Micro Devices, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. */
#include <hip/amd_detail/hip_storage.h>
#include <hip/hip_runtime.h>
#include "hip_internal.hpp"
hipError_t hipAmdFileRead(hipAmdFileHandle_t handle, void* devicePtr, uint64_t size, int64_t file_offset,
uint64_t* size_copied, int32_t* status) {
if (size == 0) {
// Skip if nothing needs reading.
return hipSuccess;
}
amd::Device* device = hip::getCurrentDevice()->devices()[0];
if (device == nullptr) {
LogError("Failed to get current device");
return hipErrorInvalidDevice;
}
#if defined(_WIN32)
amd::Os::FileDesc opaque = handle.handle;
#else
amd::Os::FileDesc opaque = handle.fd;
#endif
if (!device->amdFileRead(opaque, devicePtr, size, file_offset, size_copied, status)) {
LogError("Failed to perform file read operation");
return hipErrorUnknown;
}
return hipSuccess;
}
hipError_t hipAmdFileWrite(hipAmdFileHandle_t handle, void* devicePtr, uint64_t size, int64_t file_offset,
uint64_t* size_copied, int32_t* status) {
if (size == 0) {
// Skip if nothing needs writing.
return hipSuccess;
}
amd::Device* device = hip::getCurrentDevice()->devices()[0];
if (device == nullptr) {
LogError("Failed to get current device");
return hipErrorInvalidDevice;
}
#if defined(_WIN32)
amd::Os::FileDesc opaque = handle.handle;
#else
amd::Os::FileDesc opaque = handle.fd;
#endif
if (!device->amdFileWrite(opaque, devicePtr, size, file_offset, size_copied, status)) {
LogError("Failed to perform file write operation");
return hipErrorUnknown;
}
return hipSuccess;
}
+28 -4
Féach ar an gComhad
@@ -715,7 +715,7 @@ class Settings : public amd::HeapObject {
//! Virtual destructor as this class is used as a base class and is also used
//! to delete the derived classes.
virtual ~Settings() {};
virtual ~Settings(){};
//! Check the specified extension
bool checkExtension(uint name) const {
@@ -810,7 +810,7 @@ class Memory : public amd::HeapObject {
};
//! Default destructor for the device memory object
virtual ~Memory() {};
virtual ~Memory(){};
//! Releases virtual objects associated with this memory
void releaseVirtual();
@@ -1009,7 +1009,7 @@ class Sampler : public amd::HeapObject {
Sampler() : hwSrd_(0), hwState_(nullptr) {}
//! Default destructor for the device memory object
virtual ~Sampler() {};
virtual ~Sampler(){};
//! Returns device specific HW state for the sampler
uint64_t hwSrd() const { return hwSrd_; }
@@ -1605,7 +1605,7 @@ class Isa {
uint32_t memChannelBankWidth_; //!< Memory channel bank width.
uint32_t localMemSizePerCU_; //!< Local memory size per CU.
uint32_t localMemBanks_; //!< Number of banks of local memory.
}; // class Isa
}; // class Isa
/*! \addtogroup Runtime
* @{
@@ -1806,6 +1806,30 @@ class Device : public RuntimeObject {
virtual bool globalFreeMemory(size_t* freeMemory //!< Free memory information on a GPU device
) const = 0;
/**
* @brief Read data from a file to device memory.
* @param[IN] handle: file descriptor of the file to read.
* @param[IN] devicePtr: VRAM buffer pointer.
* @param[IN] size: size of read.
* @param[IN] file_offset: offset into fd where data has to be read.
* @param[IN/OUT] size_copied: actual size read.
* @param[IN/OUT] status: additional status.
*/
virtual bool amdFileRead(amd::Os::FileDesc handle, void* devicePtr, uint64_t size, int64_t file_offset,
uint64_t* size_copied, int32_t* status) = 0;
/**
* Write data from device memory to a file.
* @param[IN] handle: file descriptor of the file to write.
* @param[IN] devicePtr: VRAM buffer pointer.
* @param[IN] size: size of write.
* @param[IN] file_offset: offset into fd where data has to written.
* @param[IN/OUT] size_copied: actual size copied.
* @param[IN/OUT] status: additional status.
*/
virtual bool amdFileWrite(amd::Os::FileDesc handle, void* devicePtr, uint64_t size, int64_t file_offset,
uint64_t* size_copied, int32_t* status) = 0;
virtual bool importExtSemaphore(void** extSemaphore, const amd::Os::FileDesc& handle,
amd::ExternalSemaphoreHandleType sem_handle_type) = 0;
virtual void DestroyExtSemaphore(void* extSemaphore) = 0;
+21
Féach ar an gComhad
@@ -2138,6 +2138,27 @@ bool Device::globalFreeMemory(size_t* freeMemory) const {
return true;
}
// PAL Device file I/O stubs: PAL doesn't implement AIS file I/O yet.
// Provide definitions so the vtable and linker are satisfied.
// Replace with a real implementation if/when PAL supports file I/O.
bool Device::amdFileRead(amd::Os::FileDesc handle, void* devicePtr, uint64_t size, int64_t file_offset,
uint64_t* size_copied, int32_t* status) {
if (size_copied) {
*size_copied = 0;
}
LogError("PAL Device: amdFileRead not supported on this backend");
return false;
}
bool Device::amdFileWrite(amd::Os::FileDesc handle, void* devicePtr, uint64_t size, int64_t file_offset,
uint64_t* size_copied, int32_t* status) {
if (size_copied) {
*size_copied = 0;
}
LogError("PAL Device: amdFileWrite not supported on this backend");
return false;
}
amd::Memory* Device::findMapTarget(size_t size) const {
// Must be serialised for access
amd::ScopedLock lk(mapCacheOps_);
+38
Féach ar an gComhad
@@ -135,6 +135,20 @@ class NullDevice : public amd::Device {
//! Empty implementation on Null device
virtual bool globalFreeMemory(size_t* freeMemory) const { return false; }
//! Empty implementation on Null device
virtual bool amdFileRead(amd::Os::FileDesc handle, void* devicePtr, uint64_t size, int64_t file_offset,
uint64_t* size_copied, int32_t* status) {
ShouldNotReachHere();
return false;
}
//! Empty implementation on Null device
virtual bool amdFileWrite(amd::Os::FileDesc handle, void* devicePtr, uint64_t size, int64_t file_offset,
uint64_t* size_copied, int32_t* status) {
ShouldNotReachHere();
return false;
}
//! Get GPU device settings
const pal::Settings& settings() const { return reinterpret_cast<pal::Settings&>(*settings_); }
virtual void* svmAlloc(amd::Context& context, size_t size, size_t alignment,
@@ -443,6 +457,30 @@ class Device : public NullDevice {
//! Retrieves information about free memory on a GPU device
virtual bool globalFreeMemory(size_t* freeMemory) const;
/**
* @brief Read data from a file to device memory.
* @param[IN] handle: file descriptor of the file to read.
* @param[IN] devicePtr: VRAM buffer pointer.
* @param[IN] size: size of read.
* @param[IN] file_offset: offset into fd where data has to be read.
* @param[IN/OUT] size_copied: actual size read.
* @param[IN/OUT] status: additional status.
*/
virtual bool amdFileRead(amd::Os::FileDesc handle, void* devicePtr, uint64_t size, int64_t file_offset,
uint64_t* size_copied, int32_t* status);
/**
* Write data from device memory to a file.
* @param[IN] handle: file descriptor of the file to write.
* @param[IN] devicePtr: VRAM buffer pointer.
* @param[IN] size: size of write.
* @param[IN] file_offset: offset into fd where data has to written.
* @param[IN/OUT] size_copied: actual size copied.
* @param[IN/OUT] status: additional status.
*/
virtual bool amdFileWrite(amd::Os::FileDesc handle, void* devicePtr, uint64_t size, int64_t file_offset,
uint64_t* size_copied, int32_t* status);
//! Returns a GPU memory object from AMD memory object
pal::Memory* getGpuMemory(amd::Memory* mem //!< Pointer to AMD memory object
) const;
+34
Féach ar an gComhad
@@ -1722,6 +1722,40 @@ bool Device::globalFreeMemory(size_t* freeMemory) const {
return true;
}
bool Device::amdFileRead(amd::Os::FileDesc handle, void* devicePtr, uint64_t size, int64_t file_offset,
uint64_t* size_copied, int32_t* status) {
hsa_amd_ais_file_handle_t fh{};
#if defined(_WIN32)
fh.handle = handle;
#else
fh.fd = handle;
#endif
hsa_status_t ret = Hsa::ais_file_read(fh,
devicePtr, size, file_offset, size_copied, status);
if (HSA_STATUS_SUCCESS != ret) {
LogPrintfError("hsa_amd_ais_file_read operation failed with err 0x%xh", ret);
return false;
}
return true;
}
bool Device::amdFileWrite(amd::Os::FileDesc handle, void* devicePtr, uint64_t size, int64_t file_offset,
uint64_t* size_copied, int32_t* status) {
hsa_amd_ais_file_handle_t fh{};
#if defined(_WIN32)
fh.handle = handle;
#else
fh.fd = handle;
#endif
hsa_status_t ret = Hsa::ais_file_write(fh,
devicePtr, size, file_offset, size_copied, status);
if (HSA_STATUS_SUCCESS != ret) {
LogPrintfError("hsa_amd_ais_file_write operation failed with err 0x%xh", ret);
return false;
}
return true;
}
bool Device::bindExternalDevice(uint flags, void* const gfxDevice[], void* gfxContext,
bool validateOnly) {
#if defined(_WIN32)
+20 -2
Féach ar an gComhad
@@ -133,7 +133,7 @@ class Sampler : public device::Sampler {
class NullDevice : public amd::Device {
public:
//! constructor
NullDevice() {};
NullDevice(){};
//! create the device
bool create(const amd::Isa& isa);
@@ -279,6 +279,20 @@ class NullDevice : public amd::Device {
return false;
}
//! Empty implementation on Null device
bool amdFileRead(amd::Os::FileDesc handle, void* devicePtr, uint64_t size, int64_t file_offset,
uint64_t* size_copied, int32_t* status) override {
ShouldNotReachHere();
return false;
}
//! Empty implementation on Null device
bool amdFileWrite(amd::Os::FileDesc handle, void* devicePtr, uint64_t size, int64_t file_offset,
uint64_t* size_copied, int32_t* status) override {
ShouldNotReachHere();
return false;
}
bool SetClockMode(const cl_set_device_clock_mode_input_amd setClockModeInput,
cl_set_device_clock_mode_output_amd* pSetClockModeOutput) override {
return true;
@@ -407,6 +421,11 @@ class Device : public NullDevice {
const void* agentInfo = nullptr) const override; // nullptr uses default CPU agent
virtual void hostFree(void* ptr, size_t size = 0) const;
virtual bool amdFileRead(amd::Os::FileDesc handle, void* devicePtr, uint64_t size, int64_t file_offset,
uint64_t* size_copied, int32_t* status) override;
virtual bool amdFileWrite(amd::Os::FileDesc handle, void* devicePtr, uint64_t size, int64_t file_offset,
uint64_t* size_copied, int32_t* status) override;
bool deviceAllowAccess(void* dst) const;
bool allowPeerAccess(device::Memory* memory) const;
@@ -680,4 +699,3 @@ void callbackQueue(hsa_status_t status, hsa_queue_t* queue, void* data);
/**
* @}
*/
+2
Féach ar an gComhad
@@ -126,6 +126,8 @@ bool Hsa::LoadLib() {
GET_ROCR_SYMBOL(hsa_amd_vmem_address_reserve_align)
GET_ROCR_SYMBOL(hsa_amd_enable_logging)
GET_ROCR_SYMBOL(hsa_amd_memory_get_preferred_copy_engine)
GET_ROCR_SYMBOL(hsa_amd_ais_file_read)
GET_ROCR_SYMBOL(hsa_amd_ais_file_write)
// Image extensions
GET_ROCR_SYMBOL(hsa_ext_image_data_get_info)
+14
Féach ar an gComhad
@@ -135,6 +135,8 @@ struct RocrEntryPoints {
decltype(hsa_amd_vmem_address_reserve_align)* hsa_amd_vmem_address_reserve_align_;
decltype(hsa_amd_enable_logging)* hsa_amd_enable_logging_;
decltype(hsa_amd_memory_get_preferred_copy_engine)* hsa_amd_memory_get_preferred_copy_engine_;
decltype(hsa_amd_ais_file_read)* hsa_amd_ais_file_read_;
decltype(hsa_amd_ais_file_write)* hsa_amd_ais_file_write_;
// Image extensions
decltype(hsa_ext_image_data_get_info)* hsa_ext_image_data_get_info_;
decltype(hsa_ext_image_create)* hsa_ext_image_create_;
@@ -505,6 +507,18 @@ class Hsa : public amd::AllStatic {
return ROCR_DYN(hsa_amd_memory_get_preferred_copy_engine)(
dst_agent, src_agent, recommended_ids_mask);
}
static hsa_status_t ais_file_read(hsa_amd_ais_file_handle_t handle, void* devicePtr,
uint64_t size, int64_t file_offset, uint64_t* size_copied,
int32_t* status) {
return ROCR_DYN(hsa_amd_ais_file_read)(handle, devicePtr, size, file_offset, size_copied,
status);
}
static hsa_status_t ais_file_write(hsa_amd_ais_file_handle_t handle, void* devicePtr,
uint64_t size, int64_t file_offset, uint64_t* size_copied,
int32_t* status) {
return ROCR_DYN(hsa_amd_ais_file_write)(handle, devicePtr, size, file_offset, size_copied,
status);
}
// Image extensions
static hsa_status_t image_create(hsa_agent_t agent,