SWDEV-417244 - Create Unique File Desc Store and guarantee no duplicates fds are opened.
Change-Id: I7be7fee52b673f0b1b3facdfbd847b57f2a47cde
[ROCm/clr commit: 85b645731c]
This commit is contained in:
committed by
Karthik Jayaprakash
parent
c0bb71bd74
commit
22bc3d52a3
@@ -24,6 +24,7 @@ THE SOFTWARE.
|
||||
|
||||
#include <unordered_map>
|
||||
#include "hip_code_object.hpp"
|
||||
#include "hip_platform.hpp"
|
||||
|
||||
namespace hip {
|
||||
|
||||
@@ -50,28 +51,50 @@ FatBinaryInfo::FatBinaryInfo(const char* fname, const void* image) : fdesc_(amd:
|
||||
|
||||
FatBinaryInfo::~FatBinaryInfo() {
|
||||
|
||||
for (auto* fbd: fatbin_dev_info_) {
|
||||
if (fbd != nullptr) {
|
||||
delete fbd;
|
||||
if (!HIP_USE_RUNTIME_UNBUNDLER) {
|
||||
// Using COMGR Unbundler
|
||||
if (ufd_ && ufd_->fdesc_ > 0) {
|
||||
// Check for ufd_ != nullptr, since sometimes, we never create unique_file_desc.
|
||||
if (ufd_->fsize_ && image_mapped_
|
||||
&& !amd::Os::MemoryUnmapFile(image_, ufd_->fsize_)) {
|
||||
LogPrintfError("Cannot unmap file for fdesc: %d fsize: %d", ufd_->fdesc_, ufd_->fsize_);
|
||||
assert(false);
|
||||
}
|
||||
if (!PlatformState::instance().CloseUniqueFileHandle(ufd_)) {
|
||||
LogPrintfError("Cannot close file for fdesc: %d", ufd_->fdesc_);
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fdesc_ > 0) {
|
||||
if (fsize_
|
||||
&& (HIP_USE_RUNTIME_UNBUNDLER || image_mapped_)
|
||||
&& !amd::Os::MemoryUnmapFile(image_, fsize_)) {
|
||||
guarantee(false, "Cannot unmap file for fdesc: %d fsize: %d \n", fdesc_, fsize_);
|
||||
}
|
||||
if (!amd::Os::CloseFileHandle(fdesc_)) {
|
||||
guarantee(false, "Cannot close file for fdesc: %d \n", fdesc_);
|
||||
}
|
||||
}
|
||||
fname_ = std::string();
|
||||
fdesc_ = amd::Os::FDescInit();
|
||||
fsize_ = 0;
|
||||
image_ = nullptr;
|
||||
uri_ = std::string();
|
||||
|
||||
fname_ = std::string();
|
||||
fdesc_ = amd::Os::FDescInit();
|
||||
fsize_ = 0;
|
||||
image_ = nullptr;
|
||||
uri_ = std::string();
|
||||
if (0 == PlatformState::instance().UfdMapSize()) {
|
||||
LogError("All Unique FDs are closed");
|
||||
}
|
||||
|
||||
} else {
|
||||
// Using Runtime Unbundler
|
||||
if (fdesc_ > 0) {
|
||||
if (fsize_ && !amd::Os::MemoryUnmapFile(image_, fsize_)) {
|
||||
LogPrintfError("Cannot unmap file for fdesc: %d fsize: %d", fdesc_, fsize_);
|
||||
assert(false);
|
||||
}
|
||||
if (!amd::Os::CloseFileHandle(fdesc_)) {
|
||||
LogPrintfError("Cannot close file for fdesc: %d", fdesc_);
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
fname_ = std::string();
|
||||
fdesc_ = amd::Os::FDescInit();
|
||||
fsize_ = 0;
|
||||
image_ = nullptr;
|
||||
uri_ = std::string();
|
||||
}
|
||||
}
|
||||
|
||||
void ListAllDeviceWithNoCOFromBundle(const std::unordered_map<std::string,
|
||||
@@ -108,18 +131,21 @@ hipError_t FatBinaryInfo::ExtractFatBinaryUsingCOMGR(const std::vector<hip::Devi
|
||||
// COMGR file slice APIs.
|
||||
if (fname_.size() > 0) {
|
||||
// Get File Handle & size of the file.
|
||||
if (!amd::Os::GetFileHandle(fname_.c_str(), &fdesc_, &fsize_))
|
||||
ufd_ = PlatformState::instance().GetUniqueFileHandle(fname_.c_str());
|
||||
if (ufd_ == nullptr) {
|
||||
return hipErrorFileNotFound;
|
||||
}
|
||||
|
||||
// If the file name exists but the file size is 0, the something wrong with the file or its path
|
||||
if (fsize_ == 0)
|
||||
if (ufd_->fsize_ == 0) {
|
||||
return hipErrorInvalidValue;
|
||||
}
|
||||
|
||||
// If image_ is nullptr, then file path is passed via hipMod* APIs, so map the file.
|
||||
if (image_ == nullptr) {
|
||||
if(!amd::Os::MemoryMapFileDesc(fdesc_, fsize_, foffset_, &image_)) {
|
||||
if(!amd::Os::MemoryMapFileDesc(ufd_->fdesc_, ufd_->fsize_, foffset_, &image_)) {
|
||||
LogError("Cannot map the file descriptor");
|
||||
amd::Os::CloseFileHandle(fdesc_);
|
||||
PlatformState::instance().CloseUniqueFileHandle(ufd_);
|
||||
return hipErrorInvalidValue;
|
||||
}
|
||||
image_mapped_ = true;
|
||||
@@ -396,4 +422,4 @@ hipError_t FatBinaryInfo::BuildProgram(const int device_id) {
|
||||
return hipSuccess;
|
||||
}
|
||||
|
||||
} //namespace : hip
|
||||
} //namespace : hip
|
||||
@@ -28,6 +28,9 @@ THE SOFTWARE.
|
||||
#include "hip_internal.hpp"
|
||||
#include "platform/program.hpp"
|
||||
|
||||
// Forward declaration for Unique FD
|
||||
struct UniqueFD;
|
||||
|
||||
namespace hip {
|
||||
|
||||
//Fat Binary Per Device info
|
||||
@@ -66,7 +69,6 @@ public:
|
||||
hipError_t AddDevProgram(const int device_id);
|
||||
hipError_t BuildProgram(const int device_id);
|
||||
|
||||
|
||||
// Device Id bounds check
|
||||
inline void DeviceIdCheck(const int device_id) const {
|
||||
guarantee(device_id >= 0, "Invalid DeviceId less than 0");
|
||||
@@ -91,22 +93,24 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
std::string fname_; // File name
|
||||
amd::Os::FileDesc fdesc_; // File descriptor
|
||||
size_t fsize_; // Total file size
|
||||
size_t foffset_; // File Offset where the fat binary is present.
|
||||
std::string fname_; //!< File name
|
||||
amd::Os::FileDesc fdesc_; //!< File descriptor
|
||||
size_t fsize_; //!< Total file size
|
||||
size_t foffset_; //!< File Offset where the fat binary is present.
|
||||
|
||||
// Even when file is passed image will be mmapped till ~desctructor.
|
||||
const void* image_; // Image
|
||||
bool image_mapped_; // flag to detect if image is mapped
|
||||
const void* image_; //!< Image
|
||||
bool image_mapped_; //!< flag to detect if image is mapped
|
||||
|
||||
// Only used for FBs where image is directly passed
|
||||
std::string uri_; // Uniform resource indicator
|
||||
std::string uri_; //!< Uniform resource indicator
|
||||
|
||||
// Per Device Info, like corresponding binary ptr, size.
|
||||
std::vector<FatBinaryDeviceInfo*> fatbin_dev_info_;
|
||||
|
||||
std::shared_ptr<UniqueFD> ufd_; //!< Unique file descriptor
|
||||
};
|
||||
|
||||
}; /* namespace hip */
|
||||
}; // namespace hip
|
||||
|
||||
#endif /* HIP_FAT_BINARY_HPP */
|
||||
#endif // HIP_FAT_BINARY_HPP
|
||||
|
||||
@@ -897,3 +897,33 @@ void PlatformState::popExec(ihipExec_t& exec) {
|
||||
exec = std::move(hip::tls.exec_stack_.top());
|
||||
hip::tls.exec_stack_.pop();
|
||||
}
|
||||
|
||||
std::shared_ptr<UniqueFD> PlatformState::GetUniqueFileHandle(const std::string& file_path) {
|
||||
amd::ScopedLock lock(ufd_lock_);
|
||||
|
||||
if (ufd_map_.cend() == ufd_map_.find(file_path)) {
|
||||
// Get the file desc and file size from amd::Os API
|
||||
amd::Os::FileDesc fdesc;
|
||||
size_t fsize = 0;
|
||||
if (!amd::Os::GetFileHandle(file_path.c_str(), &fdesc, &fsize)) {
|
||||
return nullptr;
|
||||
}
|
||||
ufd_map_.insert(std::make_pair(file_path, std::make_shared<UniqueFD>(file_path, fdesc, fsize)));
|
||||
}
|
||||
|
||||
// we should have an entry at this time.
|
||||
return ufd_map_[file_path];
|
||||
}
|
||||
|
||||
bool PlatformState::CloseUniqueFileHandle(const std::shared_ptr<UniqueFD>& ufd) {
|
||||
amd::ScopedLock lock(ufd_lock_);
|
||||
|
||||
// if use_count is 2, then there is 1 entry in the map and the current entry is the last close.
|
||||
if (ufd.use_count() == 2) {
|
||||
ufd_map_.erase(ufd->fpath_);
|
||||
if (!amd::Os::CloseFileHandle(ufd->fdesc_)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -31,10 +31,23 @@ hipError_t ihipOccupancyMaxActiveBlocksPerMultiprocessor(
|
||||
hipFunction_t func, int inputBlockSize, size_t dynamicSMemSize, bool bCalcPotentialBlkSz);
|
||||
} /* namespace hip_impl*/
|
||||
|
||||
// Unique file descriptor class
|
||||
struct UniqueFD {
|
||||
UniqueFD(const std::string& fpath, amd::Os::FileDesc fdesc, size_t fsize)
|
||||
: fpath_(fpath), fdesc_(fdesc), fsize_(fsize) {}
|
||||
|
||||
const std::string fpath_; //!< File path of this unique file
|
||||
const amd::Os::FileDesc fdesc_; //!< File Descriptor
|
||||
const size_t fsize_; //!< File Size
|
||||
};
|
||||
|
||||
class PlatformState {
|
||||
amd::Monitor lock_{"Guards PlatformState globals", true};
|
||||
|
||||
/* Singleton object */
|
||||
// global level lock for unique file descritor map: ufd_map_
|
||||
amd::Monitor ufd_lock_{"Unique FD Store Lock", true};
|
||||
|
||||
// Singleton object
|
||||
static PlatformState* platform_;
|
||||
PlatformState() {}
|
||||
~PlatformState() {}
|
||||
@@ -55,7 +68,7 @@ class PlatformState {
|
||||
hipError_t getDynTexGlobalVar(textureReference* texRef, hipDeviceptr_t* dev_ptr,
|
||||
size_t* size_ptr);
|
||||
|
||||
/* Singleton instance */
|
||||
// Singleton instance
|
||||
static PlatformState& instance() {
|
||||
if (platform_ == nullptr) {
|
||||
// __hipRegisterFatBinary() will call this when app starts, thus
|
||||
@@ -87,10 +100,17 @@ class PlatformState {
|
||||
void configureCall(dim3 gridDim, dim3 blockDim, size_t sharedMem, hipStream_t stream);
|
||||
void popExec(ihipExec_t& exec);
|
||||
|
||||
std::shared_ptr<UniqueFD> GetUniqueFileHandle(const std::string& file_path);
|
||||
bool CloseUniqueFileHandle(const std::shared_ptr<UniqueFD>& ufd);
|
||||
|
||||
size_t UfdMapSize() const { return ufd_map_.size(); }
|
||||
|
||||
private:
|
||||
// Dynamic Code Object map, keyin module to get the corresponding object
|
||||
std::unordered_map<hipModule_t, hip::DynCO*> dynCO_map_;
|
||||
hip::StatCO statCO_; // Static Code object var
|
||||
hip::StatCO statCO_; //!< Static Code object var
|
||||
bool initialized_{false};
|
||||
std::unordered_map<textureReference*, std::pair<hipModule_t, std::string>> texRef_map_;
|
||||
|
||||
std::unordered_map<std::string, std::shared_ptr<UniqueFD>> ufd_map_; //!< Unique File Desc Map
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user