Skip to content
Draft
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
9 changes: 9 additions & 0 deletions AbstractAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,15 @@ struct AbstractAPI {
virtual void putProfilingMark(const std::string& name, ProfilingColors color) = 0;
virtual void popLastProfilingMark() = 0;

virtual bool canAccessPeer(int otherDeviceId) = 0;
virtual void switchPeerAccess(int otherDeviceId, bool enable) = 0;

virtual std::vector<uint8_t> makeIpcMemHandle(void* ptr) = 0;
virtual void* openIpcMemHandle(const std::vector<uint8_t>& handle) = 0;
virtual void closeIpcMemHandle(void* ptr) = 0;
virtual std::vector<uint8_t> makeIpcEventHandle(void* event) = 0;
virtual void* openIpcEventHandle(const std::vector<uint8_t>& handle) = 0;

virtual void setupPrinting(int rank) = 0;

bool hasFinalized() { return m_isFinalized; }
Expand Down
1 change: 1 addition & 0 deletions cuda.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ add_library(device ${DEVICE_LIBTYPE} device.cpp
interfaces/cuda/Streams.cu
interfaces/cuda/Graphs.cu
interfaces/cuda/Internals.cu
interfaces/cuda/Interop.cu
algorithms/cudahip/ArrayManip.cpp
algorithms/cudahip/BatchManip.cpp
algorithms/cudahip/Debugging.cpp
Expand Down
1 change: 1 addition & 0 deletions hip.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ set(DEVICE_SOURCE_FILES device.cpp
interfaces/hip/Memory.cpp
interfaces/hip/Streams.cpp
interfaces/hip/Graphs.cpp
interfaces/hip/Interop.cpp
algorithms/cudahip/ArrayManip.cpp
algorithms/cudahip/BatchManip.cpp
algorithms/cudahip/Debugging.cpp
Expand Down
10 changes: 10 additions & 0 deletions interfaces/cuda/CudaWrappedAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <vector>

namespace device {

class ConcreteAPI : public AbstractAPI {
public:
ConcreteAPI();
Expand Down Expand Up @@ -111,6 +112,15 @@ class ConcreteAPI : public AbstractAPI {

bool isUnifiedMemoryDefault() override;

bool canAccessPeer(int otherDeviceId) override;
void switchPeerAccess(int otherDeviceId, bool enable) override;

std::vector<uint8_t> makeIpcMemHandle(void* ptr) override;
void* openIpcMemHandle(const std::vector<uint8_t>& handle) override;
void closeIpcMemHandle(void* ptr) override;
std::vector<uint8_t> makeIpcEventHandle(void* event) override;
void* openIpcEventHandle(const std::vector<uint8_t>& handle) override;

void setupPrinting(int rank) override;

private:
Expand Down
69 changes: 69 additions & 0 deletions interfaces/cuda/Interop.cu
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// SPDX-FileCopyrightText: 2026 SeisSol Group
//
// SPDX-License-Identifier: BSD-3-Clause

#include "AbstractAPI.h"
#include "CudaWrappedAPI.h"
#include "Internals.h"
#include "utils/logger.h"

using namespace device;

namespace {

template <typename T>
std::vector<uint8_t> serialize(const T& data) {
std::vector<uint8_t> ser(sizeof(T));
memcpy(ser.data(), &data, sizeof(T));
return ser;
}

template <typename T>
T deserialize(const std::vector<uint8_t>& ser) {
T data{};
memcpy(&data, ser.data(), sizeof(T));
return data;
}

} // namespace

bool ConcreteAPI::canAccessPeer(int otherDeviceId) {
int result = 0;
APIWRAP(cudaDeviceCanAccessPeer(&result, getDeviceId(), otherDeviceId));
return result != 0;
}

void ConcreteAPI::switchPeerAccess(int otherDeviceId, bool enable) {
if (enable) {
APIWRAP(cudaDeviceEnablePeerAccess(otherDeviceId, 0));
} else {
APIWRAP(cudaDeviceDisablePeerAccess(otherDeviceId));
}
}

std::vector<uint8_t> ConcreteAPI::makeIpcMemHandle(void* ptr) {
cudaIpcMemHandle_t handle{};
APIWRAP(cudaIpcGetMemHandle(&handle, ptr));
return serialize(handle);
}

void* ConcreteAPI::openIpcMemHandle(const std::vector<uint8_t>& handle) {
void* ptr = nullptr;
APIWRAP(cudaIpcOpenMemHandle(
&ptr, deserialize<cudaIpcMemHandle_t>(handle), cudaIpcMemLazyEnablePeerAccess));
return ptr;
}

void ConcreteAPI::closeIpcMemHandle(void* ptr) { APIWRAP(cudaIpcCloseMemHandle(ptr)); }

std::vector<uint8_t> ConcreteAPI::makeIpcEventHandle(void* event) {
cudaIpcEventHandle_t handle{};
APIWRAP(cudaIpcGetEventHandle(&handle, static_cast<cudaEvent_t>(event)));
return serialize(handle);
}

void* ConcreteAPI::openIpcEventHandle(const std::vector<uint8_t>& handle) {
cudaEvent_t event{};
APIWRAP(cudaIpcOpenEventHandle(&event, deserialize<cudaIpcEventHandle_t>(handle)));
return static_cast<void*>(event);
}
9 changes: 9 additions & 0 deletions interfaces/hip/HipWrappedAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,15 @@ class ConcreteAPI : public AbstractAPI {

bool isUnifiedMemoryDefault() override;

bool canAccessPeer(int otherDeviceId) override;
void switchPeerAccess(int otherDeviceId, bool enable) override;

std::vector<uint8_t> makeIpcMemHandle(void* ptr) override;
void* openIpcMemHandle(const std::vector<uint8_t>& handle) override;
void closeIpcMemHandle(void* ptr) override;
std::vector<uint8_t> makeIpcEventHandle(void* event) override;
void* openIpcEventHandle(const std::vector<uint8_t>& handle) override;

void setupPrinting(int rank) override;

private:
Expand Down
72 changes: 72 additions & 0 deletions interfaces/hip/Interop.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// SPDX-FileCopyrightText: 2026 SeisSol Group
//
// SPDX-License-Identifier: BSD-3-Clause

#include "AbstractAPI.h"
#include "HipWrappedAPI.h"
#include "Internals.h"
#include "utils/logger.h"

#include <cstdint>
#include <vector>

using namespace device;

namespace {

template <typename T>
std::vector<uint8_t> serialize(const T& data) {
std::vector<uint8_t> ser(sizeof(T));
memcpy(ser.data(), &data, sizeof(T));
return ser;
}

template <typename T>
T deserialize(const std::vector<uint8_t>& ser) {
T data{};
memcpy(&data, ser.data(), sizeof(T));
return data;
}

} // namespace

bool ConcreteAPI::canAccessPeer(int otherDeviceId) {
int result = 0;
APIWRAP(hipDeviceCanAccessPeer(&result, getDeviceId(), otherDeviceId));
return result != 0;
}

void ConcreteAPI::switchPeerAccess(int otherDeviceId, bool enable) {
if (enable) {
APIWRAP(hipDeviceEnablePeerAccess(otherDeviceId, 0));
} else {
APIWRAP(hipDeviceDisablePeerAccess(otherDeviceId));
}
}

std::vector<uint8_t> ConcreteAPI::makeIpcMemHandle(void* ptr) {
hipIpcMemHandle_t handle{};
APIWRAP(hipIpcGetMemHandle(&handle, ptr));
return serialize(handle);
}

void* ConcreteAPI::openIpcMemHandle(const std::vector<uint8_t>& handle) {
void* ptr = nullptr;
APIWRAP(hipIpcOpenMemHandle(
&ptr, deserialize<hipIpcMemHandle_t>(handle), hipIpcMemLazyEnablePeerAccess));
return ptr;
}

void ConcreteAPI::closeIpcMemHandle(void* ptr) { APIWRAP(hipIpcCloseMemHandle(ptr)); }

std::vector<uint8_t> ConcreteAPI::makeIpcEventHandle(void* event) {
hipIpcEventHandle_t handle{};
APIWRAP(hipIpcGetEventHandle(&handle, static_cast<hipEvent_t>(event)));
return serialize(handle);
}

void* ConcreteAPI::openIpcEventHandle(const std::vector<uint8_t>& handle) {
hipEvent_t event{};
APIWRAP(hipIpcOpenEventHandle(&event, deserialize<hipIpcEventHandle_t>(handle)));
return static_cast<void*>(event);
}
9 changes: 9 additions & 0 deletions interfaces/sycl/SyclWrappedAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,15 @@ class ConcreteAPI : public AbstractAPI {

bool isUnifiedMemoryDefault() override;

bool canAccessPeer(int otherDeviceId) override;
void switchPeerAccess(int otherDeviceId, bool enable) override;

std::vector<uint8_t> makeIpcMemHandle(void* ptr) override;
void* openIpcMemHandle(const std::vector<uint8_t>& handle) override;
void closeIpcMemHandle(void* ptr) override;
std::vector<uint8_t> makeIpcEventHandle(void* event) override;
void* openIpcEventHandle(const std::vector<uint8_t>& handle) override;

void setupPrinting(int rank) override;

private:
Expand Down
Loading