Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clients/common/blis_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

void setup_blis()
{
#ifndef WIN32
#ifndef _WIN32
bli_init();
#endif
}
Expand Down
18 changes: 9 additions & 9 deletions clients/common/hipblaslt_init_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ __device__ int8_t random_hpl(size_t idx)
}

template <typename T>
void hipblaslt_init_device(ABC abc,
void hipblaslt_init_device(ABC_dims abc,
hipblaslt_initialization init,
bool is_nan,
T* A,
Expand All @@ -140,11 +140,11 @@ void hipblaslt_init_device(ABC abc,
switch(init)
{
case hipblaslt_initialization::rand_int:
if(abc == ABC::A || abc == ABC::C)
if(abc == ABC_dims::A || abc == ABC_dims::C)
fill_batch(A, M, N, lda, stride, batch_count, [](size_t idx) -> T {
return random_int<T>(idx);
});
else if(abc == ABC::B)
else if(abc == ABC_dims::B)
{
stride = std::max(lda * N, stride);
fill_batch(A, M, N, lda, stride, batch_count, [stride, lda](size_t idx) -> T {
Expand All @@ -158,14 +158,14 @@ void hipblaslt_init_device(ABC abc,
break;
case hipblaslt_initialization::trig_float:
stride = std::max(lda * N, stride);
if(abc == ABC::A || abc == ABC::C)
if(abc == ABC_dims::A || abc == ABC_dims::C)
fill_batch(A, M, N, lda, stride, batch_count, [M, N, stride, lda](size_t idx) -> T {
auto b = idx / stride;
auto j = (idx - b * stride) / lda;
auto i = (idx - b * stride) - j * lda;
return T(sin(double(i + j * M + b * M * N)));
});
else if(abc == ABC::B)
else if(abc == ABC_dims::B)
fill_batch(A, M, N, lda, stride, batch_count, [M, N, stride, lda](size_t idx) -> T {
auto b = idx / stride;
auto j = (idx - b * stride) / lda;
Expand All @@ -179,15 +179,15 @@ void hipblaslt_init_device(ABC abc,
});
break;
case hipblaslt_initialization::special:
if(abc == ABC::A)
if(abc == ABC_dims::A)
fill_batch(A, M, N, lda, stride, batch_count, [](size_t idx) -> T {
return T(hipblasLtHalf(65280.0));
});
else if(abc == ABC::B)
else if(abc == ABC_dims::B)
fill_batch(A, M, N, lda, stride, batch_count, [](size_t idx) -> T {
return T(hipblasLtHalf(0.0000607967376708984375));
});
else if(abc == ABC::C)
else if(abc == ABC_dims::C)
fill_batch(A, M, N, lda, stride, batch_count, [](size_t idx) -> T {
return T(pseudo_random_device(idx) % 10 + 1.f);
});
Expand All @@ -213,7 +213,7 @@ void hipblaslt_init_device(ABC abc,
}
}

void hipblaslt_init_device(ABC abc,
void hipblaslt_init_device(ABC_dims abc,
hipblaslt_initialization init,
bool is_nan,
void* A,
Expand Down
5 changes: 4 additions & 1 deletion clients/common/hipblaslt_parse_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,16 @@
// Parse YAML data
static std::string hipblaslt_parse_yaml(const std::string& yaml)
{
// TODO: This function is inherently unsafe because it returns a string vs an open
// file handle which will block further colliding creates. See comments in
// hipblaslt_tempname() and under no circumstances copy this to new code.
std::string tmp = hipblaslt_tempname();
auto exepath = hipblaslt_exepath();
auto cmd = exepath + "hipblaslt_gentest.py --template " + exepath
+ "hipblaslt_template.yaml -o " + tmp + " " + yaml;
hipblaslt_cerr << cmd << std::endl;

#ifdef WIN32
#ifdef _WIN32
int status = std::system(cmd.c_str());
if(status == -1)
exit(EXIT_FAILURE);
Expand Down
88 changes: 72 additions & 16 deletions clients/common/utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,23 @@
*
*******************************************************************************/

#include "utility.hpp"
#ifdef _WIN32
#include <windows.h>
// Must include windows.h before dependent headers.
#include <libloaderapi.h>
#endif

#include "d_vector.hpp"
#include "utility.hpp"
#include <atomic>
#include <chrono>
#include <cstdlib>
#include <fcntl.h>
#include <limits.h>
#include <new>
#include <stdexcept>
#include <stdlib.h>

#include <fcntl.h>

#include "Tensile/Source/client/include/Utility.hpp"

#if __has_include(<filesystem>)
Expand All @@ -48,27 +55,65 @@ namespace fs = std::experimental::filesystem;

/* ============================================================================================ */
// Return path of this executable
std::string hipblaslt_exepath()
static std::string get_self_path()
{
std::string pathstr;
char* path = realpath("/proc/self/exe", 0);
if(path)
#ifdef _WIN32
std::string result(MAX_PATH + 1, '\0');
DWORD length = 0;
for(;;)
{
char* p = strrchr(path, '/');
if(p)
length = GetModuleFileNameA(nullptr, result.data(), result.size());
if(length < result.size() - 1)
{
p[1] = 0;
pathstr = path;
result.resize(length);
return result;
}
free(path);
result.resize(result.size() * 2);
}
return pathstr;
#else
return std::string(realpath("/proc/self/exe", 0));

@bstefanuk bstefanuk Apr 25, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If realpath cannot resolve /proc/self/exe then a nullptr is returned, which would cause undefined behaviour here when constructing the std::string. However, I understand this is an edge case and I'm not too familiar with /proc/self/exe. Is this guaranteed to be defined on all Posix-compliant systems?

#endif
}

std::string hipblaslt_exepath()
{
fs::path exepath(get_self_path());
exepath.remove_filename();
std::string result = exepath.string();
if(result.empty())
result.append("/");
return result;
}

/* ============================================================================================ */
// Temp directory rooted random path
// TODO: This function is inherently unsafe because it returns a string vs an open
// file handle which will block further colliding creates. On Posix, this will leak
// a file handle for the life of the process. On Windows, there is no way to ensure that
// the created file name is unique without racing. To counter this on Windows, we
// also include the process id and a process specific counter in the generated name,
// as that will at least race consistently vs based on a random number generator
// collision. This and its consumers should be rewritten and under no circumstances
// copied to new code.
std::string hipblaslt_tempname()
{
#ifdef _WIN32
static std::atomic<int> counter;
// Generate "/tmp/rocblas-XXXXXX" like file name
const std::string alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv";
int stringlength = alphanum.length() - 1;
std::string uniquestr = "hipblaslt-";
uniquestr.append(std::to_string(GetCurrentProcessId()));
uniquestr.append("-");
uniquestr.append(std::to_string(counter.fetch_add(1)));
uniquestr.append("-");

for(auto n : {0, 1, 2, 3, 4, 5})
uniquestr += alphanum.at(rand() % stringlength);

fs::path tmpname = fs::temp_directory_path() / uniquestr;
return tmpname.string();
#else
char tmp[] = "/tmp/hipblaslt-XXXXXX";
int fd = mkostemp(tmp, O_CLOEXEC);
if(fd == -1)
Expand All @@ -78,6 +123,7 @@ std::string hipblaslt_tempname()
}

return std::string(tmp);
#endif
}

/* ============================================================================================ */
Expand Down Expand Up @@ -145,7 +191,7 @@ double get_time_us_no_sync(void)

/* ============================================================================================ */
/* device query and print out their ID and name; return number of compute-capable devices. */
int64_t query_device_property(int device_id, hipDeviceProp_t &props)
int64_t query_device_property(int device_id, hipDeviceProp_t& props)
{
int device_count;
hipblasStatus_t status = (hipblasStatus_t)hipGetDeviceCount(&device_count);
Expand Down Expand Up @@ -230,6 +276,15 @@ hipblaslt_local_handle::hipblaslt_local_handle()
#endif
}

static void portable_setenv(const char* name, const char* value)
{
#ifdef _WIN32
_putenv_s(name, value);
#else
setenv(name, value, /*overwrite=*/true);
#endif
}

hipblaslt_local_handle::hipblaslt_local_handle(const Arguments& arg)
: hipblaslt_local_handle()
{
Expand All @@ -239,7 +294,8 @@ hipblaslt_local_handle::hipblaslt_local_handle(const Arguments& arg)
if(sol_selec_env)
m_sol_selec_saved_status = std::string(sol_selec_env);
m_sol_selec_env_set = true;
setenv("TENSILE_SOLUTION_SELECTION_METHOD", std::to_string(arg.tensile_solution_selection_method).c_str(), true);
portable_setenv("TENSILE_SOLUTION_SELECTION_METHOD",
std::to_string(arg.tensile_solution_selection_method).c_str());
}
// memory guard control, with multi-threading should not change values across threads
d_vector_set_pad_length(arg.pad);
Expand All @@ -249,7 +305,7 @@ hipblaslt_local_handle::~hipblaslt_local_handle()
{
if(m_sol_selec_env_set)
{
setenv("TENSILE_SOLUTION_SELECTION_METHOD", m_sol_selec_saved_status.c_str(), true);
portable_setenv("TENSILE_SOLUTION_SELECTION_METHOD", m_sol_selec_saved_status.c_str());
}
hipblasLtDestroy(m_handle);
}
Expand Down
16 changes: 8 additions & 8 deletions clients/gtest/hipblaslt_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#include <cstdlib>
#include <exception>
#include <regex>
#ifdef WIN32
#ifdef _WIN32
#include <windows.h>
#define strcasecmp(A, B) _stricmp(A, B)
#else
Expand Down Expand Up @@ -135,7 +135,7 @@ static thread_local struct
volatile sig_atomic_t enabled = false;

// sigjmp_buf describing stack frame to go back to
#ifndef WIN32
#ifndef _WIN32
sigjmp_buf sigjmp_buf_;
#else
jmp_buf sigjmp_buf_;
Expand All @@ -161,7 +161,7 @@ extern "C" void hipblaslt_test_signal_handler(int sig)
return;
}

#ifndef WIN32
#ifndef _WIN32
// If this is an alarm timeout, we abort
if(sig == SIGALRM)
{
Expand All @@ -180,7 +180,7 @@ extern "C" void hipblaslt_test_signal_handler(int sig)
// it is better than crashing.
t_handler.signal = sig;
errno = saved_errno;
#ifndef WIN32
#ifndef _WIN32
siglongjmp(t_handler.sigjmp_buf_, true);
#else
longjmp(t_handler.sigjmp_buf_, true);
Expand All @@ -190,7 +190,7 @@ extern "C" void hipblaslt_test_signal_handler(int sig)
// Set up signal handlers
void hipblaslt_test_sigaction()
{
#ifndef WIN32
#ifndef _WIN32
struct sigaction act;
act.sa_flags = 0;
sigfillset(&act.sa_mask);
Expand Down Expand Up @@ -219,7 +219,7 @@ void catch_signals_and_exceptions_as_failures(std::function<void()> test, bool s
// Save the current handler (to allow nested calls to this function)
auto old_handler = t_handler;

#ifndef WIN32
#ifndef _WIN32
// Set up the return point, and handle siglongjmp returning back to here
if(sigsetjmp(t_handler.sigjmp_buf_, true))
{
Expand All @@ -237,7 +237,7 @@ void catch_signals_and_exceptions_as_failures(std::function<void()> test, bool s
#endif
else
{
#ifndef WIN32
#ifndef _WIN32
// Alarm to detect deadlocks or hangs
if(set_alarm)
alarm(test_timeout);
Expand All @@ -260,7 +260,7 @@ void catch_signals_and_exceptions_as_failures(std::function<void()> test, bool s
}
}

#ifndef WIN32
#ifndef _WIN32
// Cancel the alarm if it was set
if(set_alarm)
alarm(0);
Expand Down
4 changes: 4 additions & 0 deletions clients/include/TensorDataManipulation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
#include <iosfwd>
#include <memory>
#include <vector>
#ifdef _WIN32
#include <BaseTsd.h>
typedef SSIZE_T ssize_t;
#endif

namespace Tensor
{
Expand Down
2 changes: 2 additions & 0 deletions clients/include/datatype_interface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
#pragma once
#include <hipblaslt/hipblaslt.h>

#include <map>

union computeTypeInterface
{
float f32;
Expand Down
2 changes: 1 addition & 1 deletion clients/include/hipblaslt_arguments.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ struct Arguments
// Function to read Arguments data from stream
friend std::istream& operator>>(std::istream& str, Arguments& arg);

#ifdef WIN32
#ifdef _WIN32
// Clang specific code
template <typename T>
friend hipblaslt_internal_ostream& operator<<(hipblaslt_internal_ostream& os,
Expand Down
4 changes: 2 additions & 2 deletions clients/include/hipblaslt_init.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@
#include <omp.h>
#include <vector>

enum class ABC
enum class ABC_dims
{
A,
B,
C
};

void hipblaslt_init_device(ABC abc,
void hipblaslt_init_device(ABC_dims ABC_dims,
hipblaslt_initialization init,
bool is_nan,
void* A,
Expand Down
Loading