16#ifndef EIGEN_GPU_DEVICE_MATRIX_H
17#define EIGEN_GPU_DEVICE_MATRIX_H
20#include "./InternalHeaderCheck.h"
25#include "./GpuSupport.h"
38template <
typename Scalar_>
41 using Scalar = Scalar_;
48 EIGEN_CUDA_RUNTIME_CHECK(cudaEventSynchronize(event_));
49 if (pinned_buf_ && host_buf_.size() > 0) {
50 std::memcpy(host_buf_.data(), pinned_buf_.get(),
static_cast<size_t>(host_buf_.size()) *
sizeof(Scalar));
52 pinned_buf_ = internal::PinnedHostBuffer();
60 if (synced_)
return true;
61 const cudaError_t err = cudaEventQuery(event_);
62 if (err == cudaSuccess)
return true;
63 if (err != cudaErrorNotReady)
64 EIGEN_GPU_CHECK_FAILED(cudaGetErrorName(err),
"cudaEventQuery(event_)", __FILE__, __LINE__);
69 if (event_) (void)cudaEventDestroy(event_);
72 HostTransfer(HostTransfer&& o) noexcept
73 : host_buf_(std::move(o.host_buf_)), pinned_buf_(std::move(o.pinned_buf_)), event_(o.event_), synced_(o.synced_) {
78 HostTransfer& operator=(HostTransfer&& o)
noexcept {
81 if (event_) (void)cudaEventDestroy(event_);
82 host_buf_ = std::move(o.host_buf_);
83 pinned_buf_ = std::move(o.pinned_buf_);
92 HostTransfer(
const HostTransfer&) =
delete;
93 HostTransfer& operator=(
const HostTransfer&) =
delete;
97 friend class DeviceMatrix;
99 HostTransfer(PlainMatrix&& buf, internal::PinnedHostBuffer&& pinned, cudaEvent_t event)
100 : host_buf_(std::move(buf)), pinned_buf_(std::move(pinned)), event_(event), synced_(false) {}
102 PlainMatrix host_buf_;
103 internal::PinnedHostBuffer pinned_buf_;
104 cudaEvent_t event_ =
nullptr;
105 bool synced_ =
false;
121template <
typename Scalar_>
124 using Scalar = Scalar_;
135 eigen_assert(n >= 0);
141 eigen_assert(rows >= 0 && cols >= 0);
150 template <
typename Lhs,
typename Rhs>
169 if (ready_event_) (void)cudaEventDestroy(ready_event_);
173 : data_(std::move(o.data_)),
176 capacity_bytes_(o.capacity_bytes_),
177 ready_event_(o.ready_event_),
178 ready_stream_(o.ready_stream_),
179 retained_buffer_(std::move(o.retained_buffer_)) {
182 o.capacity_bytes_ = 0;
183 o.ready_event_ =
nullptr;
184 o.ready_stream_ =
nullptr;
190 if (ready_event_) (void)cudaEventDestroy(ready_event_);
191 data_ = std::move(o.data_);
194 capacity_bytes_ = o.capacity_bytes_;
195 ready_event_ = o.ready_event_;
196 ready_stream_ = o.ready_stream_;
197 retained_buffer_ = std::move(o.retained_buffer_);
200 o.capacity_bytes_ = 0;
201 o.ready_event_ =
nullptr;
202 o.ready_stream_ =
nullptr;
225 template <
typename Derived>
234 internal::upload_host_matrix(dm.data_.get(), mat.rows(), mat.data(), mat.outerStride(), mat.rows(), mat.cols(),
236 EIGEN_CUDA_RUNTIME_CHECK(cudaStreamSynchronize(stream));
252 eigen_assert(rows >= 0 && cols >= 0);
253 eigen_assert(host_data !=
nullptr || (rows == 0 || cols == 0));
256 EIGEN_CUDA_RUNTIME_CHECK(
257 cudaMemcpyAsync(dm.data_.get(), host_data, dm.
sizeInBytes(), cudaMemcpyHostToDevice, stream));
270 PlainMatrix
toHost(cudaStream_t stream =
nullptr)
const {
271 PlainMatrix host_buf(rows_, cols_);
274 EIGEN_CUDA_RUNTIME_CHECK(
275 cudaMemcpyAsync(host_buf.
data(), data_.get(),
sizeInBytes(), cudaMemcpyDeviceToHost, stream));
276 EIGEN_CUDA_RUNTIME_CHECK(cudaStreamSynchronize(stream));
290 PlainMatrix host_buf(rows_, cols_);
291 internal::PinnedHostBuffer pinned_buf(
sizeInBytes());
294 EIGEN_CUDA_RUNTIME_CHECK(
295 cudaMemcpyAsync(pinned_buf.get(), data_.get(),
sizeInBytes(), cudaMemcpyDeviceToHost, stream));
297 cudaEvent_t transfer_event;
298 EIGEN_CUDA_RUNTIME_CHECK(cudaEventCreateWithFlags(&transfer_event, cudaEventDisableTiming));
299 EIGEN_CUDA_RUNTIME_CHECK(cudaEventRecord(transfer_event, stream));
311 EIGEN_CUDA_RUNTIME_CHECK(
312 cudaMemcpyAsync(result.data_.get(), data_.get(),
sizeInBytes(), cudaMemcpyDeviceToDevice, stream));
324 eigen_assert(rows >= 0 && cols >= 0);
325 if (rows == rows_ && cols == cols_)
return;
326 const size_t bytes =
static_cast<size_t>(rows) *
static_cast<size_t>(cols) *
sizeof(Scalar);
327 if (bytes > 0 && bytes <= capacity_bytes_ && data_) {
337 EIGEN_CUDA_RUNTIME_CHECK(cudaEventDestroy(ready_event_));
338 ready_event_ =
nullptr;
340 ready_stream_ =
nullptr;
347 Scalar* data() {
return data_.get(); }
348 const Scalar* data()
const {
return data_.get(); }
349 Index rows()
const {
return rows_; }
350 Index cols()
const {
return cols_; }
351 bool empty()
const {
return rows_ == 0 || cols_ == 0; }
357 bool isView()
const {
return data_ !=
nullptr && data_.get_deleter().borrow; }
360 size_t sizeInBytes()
const {
return static_cast<size_t>(rows_) *
static_cast<size_t>(cols_) *
sizeof(Scalar); }
365 EIGEN_CUDA_RUNTIME_CHECK(cudaEventRecord(ready_event_, stream));
366 ready_stream_ = stream;
373 if (ready_event_ && stream != ready_stream_) {
374 EIGEN_CUDA_RUNTIME_CHECK(cudaStreamWaitEvent(stream, ready_event_, 0));
386 Assignment<Scalar>
device(
Context& ctx) {
return Assignment<Scalar>(*
this, ctx); }
388 template <
typename Lhs,
typename Rhs>
391 template <
typename Lhs,
typename Rhs>
395 template <
typename Lhs,
typename Rhs>
471 void setZero(cudaStream_t stream);
562 dm.data_.reset(device_ptr);
579 std::unique_ptr<Scalar, internal::CudaFreeDeleter>(device_ptr, internal::CudaFreeDeleter{
true});
589 Scalar* p = data_.release();
594 EIGEN_CUDA_RUNTIME_CHECK(cudaEventDestroy(ready_event_));
595 ready_event_ =
nullptr;
597 ready_stream_ =
nullptr;
605 void allocate(
size_t bytes) {
607 data_ = std::unique_ptr<Scalar, internal::CudaFreeDeleter>(
static_cast<Scalar*
>(internal::device_malloc(bytes)),
608 internal::CudaFreeDeleter{});
609 capacity_bytes_ = bytes;
615 EIGEN_CUDA_RUNTIME_CHECK(cudaEventCreateWithFlags(&ready_event_, cudaEventDisableTiming));
619 void retainBuffer(internal::DeviceBuffer&& buffer) { retained_buffer_ = std::move(buffer); }
621 std::unique_ptr<Scalar, internal::CudaFreeDeleter> data_;
624 size_t capacity_bytes_ = 0;
625 cudaEvent_t ready_event_ =
nullptr;
626 cudaStream_t ready_stream_ =
nullptr;
627 internal::DeviceBuffer retained_buffer_;
constexpr Scalar * data()
View returned by DeviceMatrix::adjoint(); maps to the cuBLAS conjugate-transpose operand flag.
Definition DeviceExpr.h:46
Definition DeviceBlasExpr.h:81
Unified GPU execution context owning a CUDA stream and library handles.
Definition GpuContext.h:81
Linear combination of two device matrices.
Definition DeviceExpr.h:260
RAII wrapper for a dense column-major matrix in GPU device memory.
Definition DeviceMatrix.h:122
static DeviceMatrix fromHost(const DenseBase< Derived > &host, cudaStream_t stream=nullptr)
Definition DeviceMatrix.h:226
DeviceMatrix & operator*=(Scalar alpha)
Definition DeviceDispatch.h:744
LLTView< Scalar, Lower > llt() const
Definition DeviceMatrix.h:399
HostTransfer< Scalar > toHostAsync(cudaStream_t stream=nullptr) const
Definition DeviceMatrix.h:289
static DeviceMatrix fromHostAsync(const Scalar *host_data, Index rows, Index cols, cudaStream_t stream)
Definition DeviceMatrix.h:251
Scalar * release()
Definition DeviceMatrix.h:588
DeviceMatrix(Index n)
Definition DeviceMatrix.h:134
void addScaled(Context &ctx, Scalar alpha, const DeviceMatrix &x)
Definition DeviceDispatch.h:677
DeviceMatrix(Index rows, Index cols)
Definition DeviceMatrix.h:140
Assignment< Scalar > device(Context &ctx)
Definition DeviceMatrix.h:386
DeviceMatrix cwiseProduct(Context &ctx, const DeviceMatrix &other) const
Definition DeviceDispatch.h:858
TransposeView< Scalar > transpose() const
Definition DeviceMatrix.h:382
void scale(Context &ctx, Scalar alpha)
Definition DeviceDispatch.h:689
void copyFrom(Context &ctx, const DeviceMatrix &other)
Definition DeviceDispatch.h:699
size_t sizeInBytes() const
Definition DeviceMatrix.h:360
DeviceMatrix & operator/=(Scalar alpha)
Definition DeviceDispatch.h:778
LLTView< Scalar, UpLo > llt() const
Definition DeviceMatrix.h:403
bool isView() const
Definition DeviceMatrix.h:357
DeviceMatrix & operator-=(const GemmExpr< Lhs, Rhs > &expr)
void divide(Context &ctx, Scalar alpha)
Definition DeviceDispatch.h:767
ConstSelfAdjointView< Scalar, UpLo > selfadjointView() const
Definition DeviceMatrix.h:429
static DeviceMatrix view(Scalar *device_ptr, Index rows, Index cols)
Definition DeviceMatrix.h:576
static DeviceMatrix adopt(Scalar *device_ptr, Index rows, Index cols)
Definition DeviceMatrix.h:560
void recordReady(cudaStream_t stream)
Definition DeviceMatrix.h:363
DeviceMatrix clone(cudaStream_t stream=nullptr) const
Definition DeviceMatrix.h:307
AdjointView< Scalar > adjoint() const
Definition DeviceMatrix.h:379
PlainMatrix toHost(cudaStream_t stream=nullptr) const
Definition DeviceMatrix.h:270
DeviceScalar< Scalar > dot(Context &ctx, const DeviceMatrix &other) const
Definition DeviceDispatch.h:599
SelfAdjointView< Scalar, UpLo > selfadjointView()
Definition DeviceMatrix.h:423
LUView< Scalar > lu() const
Definition DeviceMatrix.h:408
void resize(Index rows, Index cols)
Definition DeviceMatrix.h:323
DeviceMatrix & noalias()
Definition DeviceMatrix.h:557
TriangularView< Scalar, UpLo > triangularView() const
Definition DeviceMatrix.h:417
void waitReady(cudaStream_t stream) const
Definition DeviceMatrix.h:372
RAII wrapper for a scalar in GPU device memory.
Definition DeviceScalar.h:33
Expression that scales a device matrix by a DeviceScalar.
Definition DeviceExpr.h:231
Expression returned by operator*(lhs_expr, rhs_expr), dispatched to cuBLAS GEMM.
Definition DeviceExpr.h:92
Future for an asynchronous device-to-host matrix transfer.
Definition DeviceMatrix.h:39
PlainMatrix & get()
Definition DeviceMatrix.h:46
bool ready() const
Definition DeviceMatrix.h:59
Definition DeviceSolverExpr.h:61
Definition DeviceSolverExpr.h:76
Definition DeviceSolverExpr.h:30
Definition DeviceSolverExpr.h:46
Expression returned by operator*(Scalar, DeviceMatrix/View), carrying the scalar factor.
Definition DeviceExpr.h:77
Definition DeviceBlasExpr.h:61
Definition GpuSparseContext.h:166
Definition GpuSparseContext.h:146
Definition DeviceBlasExpr.h:96
View returned by DeviceMatrix::transpose(); maps to the cuBLAS transpose operand flag.
Definition DeviceExpr.h:58
Definition DeviceBlasExpr.h:29
Definition DeviceBlasExpr.h:45
Internal RAII owner for an untyped GPU device allocation.
Definition GpuSupport.h:293
Namespace containing all symbols from the Eigen library.