Skip to content

Commit

Permalink
Use explicit host-device syncing (#200)
Browse files Browse the repository at this point in the history
* Matrix getters don't sync.

* Use explicit host-device syncing in tests.
  • Loading branch information
pelesh authored Oct 12, 2024
1 parent 95bb571 commit 46155fc
Show file tree
Hide file tree
Showing 11 changed files with 172 additions and 114 deletions.
4 changes: 3 additions & 1 deletion resolve/SystemSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,9 @@ namespace ReSolve
}
if (refactorizationMethod_ == "cusolverrf") {
matrix::Csc* L_csc = dynamic_cast<matrix::Csc*>(L_);
matrix::Csc* U_csc = dynamic_cast<matrix::Csc*>(U_);
matrix::Csc* U_csc = dynamic_cast<matrix::Csc*>(U_);
L_csc->syncData(memory::DEVICE);
U_csc->syncData(memory::DEVICE);
matrix::Csr* L_csr = new matrix::Csr(L_csc->getNumRows(), L_csc->getNumColumns(), L_csc->getNnz());
matrix::Csr* U_csr = new matrix::Csr(U_csc->getNumRows(), U_csc->getNumColumns(), U_csc->getNnz());
matrixHandler_->csc2csr(L_csc, L_csr, memory::DEVICE);
Expand Down
89 changes: 51 additions & 38 deletions resolve/matrix/Coo.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <cstring> // <-- includes memcpy
#include <iostream>
#include <iomanip>
#include <iomanip>
#include <cassert>

#include <resolve/utilities/logger/Logger.hpp>
#include "Coo.hpp"
Expand Down Expand Up @@ -132,7 +133,7 @@ namespace ReSolve
index_type* matrix::Coo::getRowData(memory::MemorySpace memspace)
{
using namespace ReSolve::memory;
syncData(memspace);

switch (memspace) {
case HOST:
return this->h_row_data_;
Expand All @@ -146,7 +147,7 @@ namespace ReSolve
index_type* matrix::Coo::getColData(memory::MemorySpace memspace)
{
using namespace ReSolve::memory;
syncData(memspace);

switch (memspace) {
case HOST:
return this->h_col_data_;
Expand All @@ -160,7 +161,7 @@ namespace ReSolve
real_type* matrix::Coo::getValues(memory::MemorySpace memspace)
{
using namespace ReSolve::memory;
syncData(memspace);

switch (memspace) {
case HOST:
return this->h_val_data_;
Expand Down Expand Up @@ -302,44 +303,56 @@ namespace ReSolve

switch (memspace) {
case HOST:
if ((d_data_updated_ == true) && (h_data_updated_ == false)) {
if ((h_row_data_ == nullptr) != (h_col_data_ == nullptr)) {
out::error() << "In Coo::syncData one of host row or column data is null!\n";
}
if ((h_row_data_ == nullptr) && (h_col_data_ == nullptr)) {
h_row_data_ = new index_type[nnz_];
h_col_data_ = new index_type[nnz_];
owns_cpu_data_ = true;
}
if (h_val_data_ == nullptr) {
h_val_data_ = new real_type[nnz_];
owns_cpu_vals_ = true;
}
mem_.copyArrayDeviceToHost(h_row_data_, d_row_data_, nnz_);
mem_.copyArrayDeviceToHost(h_col_data_, d_col_data_, nnz_);
mem_.copyArrayDeviceToHost(h_val_data_, d_val_data_, nnz_);
h_data_updated_ = true;
if (h_data_updated_) {
out::misc() << "In Coo::syncData trying to sync host, but host already up to date!\n";
return 0;
}
if (!d_data_updated_) {
out::error() << "In Coo::syncData trying to sync host with device, but device is out of date!\n";
assert(d_data_updated_);
}
if ((h_row_data_ == nullptr) != (h_col_data_ == nullptr)) {
out::error() << "In Coo::syncData one of host row or column data is null!\n";
}
if ((h_row_data_ == nullptr) && (h_col_data_ == nullptr)) {
h_row_data_ = new index_type[nnz_];
h_col_data_ = new index_type[nnz_];
owns_cpu_data_ = true;
}
if (h_val_data_ == nullptr) {
h_val_data_ = new real_type[nnz_];
owns_cpu_vals_ = true;
}
mem_.copyArrayDeviceToHost(h_row_data_, d_row_data_, nnz_);
mem_.copyArrayDeviceToHost(h_col_data_, d_col_data_, nnz_);
mem_.copyArrayDeviceToHost(h_val_data_, d_val_data_, nnz_);
h_data_updated_ = true;
return 0;
case DEVICE:
if ((d_data_updated_ == false) && (h_data_updated_ == true)) {
if ((d_row_data_ == nullptr) != (d_col_data_ == nullptr)) {
out::error() << "In Coo::syncData one of device row or column data is null!\n";
}
if ((d_row_data_ == nullptr) && (d_col_data_ == nullptr)) {
mem_.allocateArrayOnDevice(&d_row_data_, nnz_);
mem_.allocateArrayOnDevice(&d_col_data_, nnz_);
owns_gpu_data_ = true;
}
if (d_val_data_ == nullptr) {
mem_.allocateArrayOnDevice(&d_val_data_, nnz_);
owns_gpu_vals_ = true;
}
mem_.copyArrayHostToDevice(d_row_data_, h_row_data_, nnz_);
mem_.copyArrayHostToDevice(d_col_data_, h_col_data_, nnz_);
mem_.copyArrayHostToDevice(d_val_data_, h_val_data_, nnz_);
d_data_updated_ = true;
if (d_data_updated_) {
out::misc() << "In Coo::syncData trying to sync device, but device already up to date!\n";
return 0;
}
if (!h_data_updated_) {
out::error() << "In Coo::syncData trying to sync device with host, but host is out of date!\n";
assert(h_data_updated_);
}
if ((d_row_data_ == nullptr) != (d_col_data_ == nullptr)) {
out::error() << "In Coo::syncData one of device row or column data is null!\n";
}
if ((d_row_data_ == nullptr) && (d_col_data_ == nullptr)) {
mem_.allocateArrayOnDevice(&d_row_data_, nnz_);
mem_.allocateArrayOnDevice(&d_col_data_, nnz_);
owns_gpu_data_ = true;
}
if (d_val_data_ == nullptr) {
mem_.allocateArrayOnDevice(&d_val_data_, nnz_);
owns_gpu_vals_ = true;
}
mem_.copyArrayHostToDevice(d_row_data_, h_row_data_, nnz_);
mem_.copyArrayHostToDevice(d_col_data_, h_col_data_, nnz_);
mem_.copyArrayHostToDevice(d_val_data_, h_val_data_, nnz_);
d_data_updated_ = true;
return 0;
default:
return 1;
Expand Down
87 changes: 50 additions & 37 deletions resolve/matrix/Csc.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <cstring> // <-- includes memcpy
#include <iomanip>
#include <cassert>

#include <resolve/utilities/logger/Logger.hpp>
#include "Csc.hpp"
Expand Down Expand Up @@ -33,7 +34,7 @@ namespace ReSolve
index_type* matrix::Csc::getRowData(memory::MemorySpace memspace)
{
using namespace ReSolve::memory;
syncData(memspace);

switch (memspace) {
case HOST:
return this->h_row_data_;
Expand All @@ -47,7 +48,7 @@ namespace ReSolve
index_type* matrix::Csc::getColData(memory::MemorySpace memspace)
{
using namespace ReSolve::memory;
syncData(memspace);

switch (memspace) {
case HOST:
return this->h_col_data_;
Expand All @@ -61,7 +62,7 @@ namespace ReSolve
real_type* matrix::Csc::getValues(memory::MemorySpace memspace)
{
using namespace ReSolve::memory;
syncData(memspace);

switch (memspace) {
case HOST:
return this->h_val_data_;
Expand Down Expand Up @@ -209,44 +210,56 @@ namespace ReSolve

switch(memspace) {
case HOST:
if ((d_data_updated_ == true) && (h_data_updated_ == false)) {
if ((h_row_data_ == nullptr) != (h_col_data_ == nullptr)) {
out::error() << "In Csc::syncData one of host row or column data is null!\n";
}
if ((h_col_data_ == nullptr) && (h_row_data_ == nullptr)) {
h_col_data_ = new index_type[m_ + 1];
h_row_data_ = new index_type[nnz_];
owns_cpu_data_ = true;
}
if (h_val_data_ == nullptr) {
h_val_data_ = new real_type[nnz_];
owns_cpu_vals_ = true;
}
mem_.copyArrayDeviceToHost(h_col_data_, d_col_data_, m_ + 1);
mem_.copyArrayDeviceToHost(h_row_data_, d_row_data_, nnz_);
mem_.copyArrayDeviceToHost(h_val_data_, d_val_data_, nnz_);
h_data_updated_ = true;
if (h_data_updated_) {
out::misc() << "In Csc::syncData trying to sync host, but host already up to date!\n";
return 0;
}
if (!d_data_updated_) {
out::error() << "In Csc::syncData trying to sync host with device, but device is out of date!\n";
assert(d_data_updated_);
}
if ((h_row_data_ == nullptr) != (h_col_data_ == nullptr)) {
out::error() << "In Csc::syncData one of host row or column data is null!\n";
}
if ((h_col_data_ == nullptr) && (h_row_data_ == nullptr)) {
h_col_data_ = new index_type[m_ + 1];
h_row_data_ = new index_type[nnz_];
owns_cpu_data_ = true;
}
if (h_val_data_ == nullptr) {
h_val_data_ = new real_type[nnz_];
owns_cpu_vals_ = true;
}
mem_.copyArrayDeviceToHost(h_col_data_, d_col_data_, m_ + 1);
mem_.copyArrayDeviceToHost(h_row_data_, d_row_data_, nnz_);
mem_.copyArrayDeviceToHost(h_val_data_, d_val_data_, nnz_);
h_data_updated_ = true;
return 0;
case DEVICE:
if ((d_data_updated_ == false) && (h_data_updated_ == true)) {
if ((d_row_data_ == nullptr) != (d_col_data_ == nullptr)) {
out::error() << "In Csc::syncData one of device row or column data is null!\n";
}
if ((d_col_data_ == nullptr) && (d_row_data_ == nullptr)) {
mem_.allocateArrayOnDevice(&d_col_data_, m_ + 1);
mem_.allocateArrayOnDevice(&d_row_data_, nnz_);
owns_gpu_data_ = true;
}
if (d_val_data_ == nullptr) {
mem_.allocateArrayOnDevice(&d_val_data_, nnz_);
owns_gpu_vals_ = true;
}
mem_.copyArrayHostToDevice(d_col_data_, h_col_data_, m_ + 1);
mem_.copyArrayHostToDevice(d_row_data_, h_row_data_, nnz_);
mem_.copyArrayHostToDevice(d_val_data_, h_val_data_, nnz_);
d_data_updated_ = true;
if (d_data_updated_) {
out::misc() << "In Csc::syncData trying to sync device, but device already up to date!\n";
return 0;
}
if (!h_data_updated_) {
out::error() << "In Csc::syncData trying to sync device with host, but host is out of date!\n";
assert(h_data_updated_);
}
if ((d_row_data_ == nullptr) != (d_col_data_ == nullptr)) {
out::error() << "In Csc::syncData one of device row or column data is null!\n";
}
if ((d_col_data_ == nullptr) && (d_row_data_ == nullptr)) {
mem_.allocateArrayOnDevice(&d_col_data_, m_ + 1);
mem_.allocateArrayOnDevice(&d_row_data_, nnz_);
owns_gpu_data_ = true;
}
if (d_val_data_ == nullptr) {
mem_.allocateArrayOnDevice(&d_val_data_, nnz_);
owns_gpu_vals_ = true;
}
mem_.copyArrayHostToDevice(d_col_data_, h_col_data_, m_ + 1);
mem_.copyArrayHostToDevice(d_row_data_, h_row_data_, nnz_);
mem_.copyArrayHostToDevice(d_val_data_, h_val_data_, nnz_);
d_data_updated_ = true;
return 0;
default:
return 1;
Expand Down
88 changes: 50 additions & 38 deletions resolve/matrix/Csr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ namespace ReSolve
index_type* matrix::Csr::getRowData(memory::MemorySpace memspace)
{
using namespace ReSolve::memory;
syncData(memspace);

switch (memspace) {
case HOST:
return this->h_row_data_;
Expand All @@ -165,7 +165,7 @@ namespace ReSolve
index_type* matrix::Csr::getColData(memory::MemorySpace memspace)
{
using namespace ReSolve::memory;
syncData(memspace);

switch (memspace) {
case HOST:
return this->h_col_data_;
Expand All @@ -179,7 +179,7 @@ namespace ReSolve
real_type* matrix::Csr::getValues(memory::MemorySpace memspace)
{
using namespace ReSolve::memory;
syncData(memspace);

switch (memspace) {
case HOST:
return this->h_val_data_;
Expand Down Expand Up @@ -319,47 +319,59 @@ namespace ReSolve
switch (memspace) {
case HOST:
//check if we need to copy or not
if ((d_data_updated_ == true) && (h_data_updated_ == false)) {
if ((h_row_data_ == nullptr) != (h_col_data_ == nullptr)) {
out::error() << "In Csr::syncData one of host row or column data is null!\n";
}
if ((h_row_data_ == nullptr) && (h_col_data_ == nullptr)) {
h_row_data_ = new index_type[n_ + 1];
h_col_data_ = new index_type[nnz_];
owns_cpu_data_ = true;
}
if (h_val_data_ == nullptr) {
h_val_data_ = new real_type[nnz_];
owns_cpu_vals_ = true;
}
mem_.copyArrayDeviceToHost(h_row_data_, d_row_data_, n_ + 1);
mem_.copyArrayDeviceToHost(h_col_data_, d_col_data_, nnz_);
mem_.copyArrayDeviceToHost(h_val_data_, d_val_data_, nnz_);
h_data_updated_ = true;
if (h_data_updated_) {
out::misc() << "In Csr::syncData trying to sync host, but host already up to date!\n";
return 0;
}
if (!d_data_updated_) {
out::error() << "In Csr::syncData trying to sync host with device, but device is out of date!\n";
assert(d_data_updated_);
}
if ((h_row_data_ == nullptr) != (h_col_data_ == nullptr)) {
out::error() << "In Csr::syncData one of host row or column data is null!\n";
}
if ((h_row_data_ == nullptr) && (h_col_data_ == nullptr)) {
h_row_data_ = new index_type[n_ + 1];
h_col_data_ = new index_type[nnz_];
owns_cpu_data_ = true;
}
if (h_val_data_ == nullptr) {
h_val_data_ = new real_type[nnz_];
owns_cpu_vals_ = true;
}
mem_.copyArrayDeviceToHost(h_row_data_, d_row_data_, n_ + 1);
mem_.copyArrayDeviceToHost(h_col_data_, d_col_data_, nnz_);
mem_.copyArrayDeviceToHost(h_val_data_, d_val_data_, nnz_);
h_data_updated_ = true;
return 0;
case DEVICE:
if ((d_data_updated_ == false) && (h_data_updated_ == true)) {
if ((d_row_data_ == nullptr) != (d_col_data_ == nullptr)) {
out::error() << "In Csr::syncData one of device row or column data is null!\n";
}
if ((d_row_data_ == nullptr) && (d_col_data_ == nullptr)) {
mem_.allocateArrayOnDevice(&d_row_data_, n_ + 1);
mem_.allocateArrayOnDevice(&d_col_data_, nnz_);
owns_gpu_data_ = true;
}
if (d_val_data_ == nullptr) {
mem_.allocateArrayOnDevice(&d_val_data_, nnz_);
owns_gpu_vals_ = true;
}
mem_.copyArrayHostToDevice(d_row_data_, h_row_data_, n_ + 1);
mem_.copyArrayHostToDevice(d_col_data_, h_col_data_, nnz_);
mem_.copyArrayHostToDevice(d_val_data_, h_val_data_, nnz_);
d_data_updated_ = true;
if (d_data_updated_) {
out::misc() << "In Csr::syncData trying to sync device, but device already up to date!\n";
return 0;
}
if (!h_data_updated_) {
out::error() << "In Csr::syncData trying to sync device with host, but host is out of date!\n";
assert(h_data_updated_);
}
if ((d_row_data_ == nullptr) != (d_col_data_ == nullptr)) {
out::error() << "In Csr::syncData one of device row or column data is null!\n";
}
if ((d_row_data_ == nullptr) && (d_col_data_ == nullptr)) {
mem_.allocateArrayOnDevice(&d_row_data_, n_ + 1);
mem_.allocateArrayOnDevice(&d_col_data_, nnz_);
owns_gpu_data_ = true;
}
if (d_val_data_ == nullptr) {
mem_.allocateArrayOnDevice(&d_val_data_, nnz_);
owns_gpu_vals_ = true;
}
mem_.copyArrayHostToDevice(d_row_data_, h_row_data_, n_ + 1);
mem_.copyArrayHostToDevice(d_col_data_, h_col_data_, nnz_);
mem_.copyArrayHostToDevice(d_val_data_, h_val_data_, nnz_);
d_data_updated_ = true;
return 0;
default:
return -1;
return 1;
} // switch
}

Expand Down
Loading

0 comments on commit 46155fc

Please sign in to comment.