I’m trying to write a simple matrix class that works with OpenACC, but I’m getting a runtime error that occurs when I uncomment code that defines the multiplication operator overload (without actually using the multiplication operator when running the code). The code is as follows:
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
class Matrix {
public:
Matrix();
Matrix(const size_t num_rows, const size_t num_cols);
Matrix(const Matrix &m); // Copy constructor
~Matrix();
size_t num_rows() const;
size_t num_cols() const;
float operator()(const size_t row, const size_t col) const;
float& operator()(const size_t row, const size_t col);
Matrix& operator=(const Matrix &m); // Copy assignment operator
Matrix operator*(const Matrix &m2);
private:
float *data_;
size_t num_rows_;
size_t num_cols_;
};
Matrix::Matrix(const size_t num_rows, const size_t num_cols) :
num_rows_(num_rows),
num_cols_(num_cols)
{
// Use malloc instead of new since new can't be used if Matrix is created inside an acc routine seq function?
// For more info, see https://stackoverflow.com/questions/43497285/openacc-the-c-new-operator-issue
data_ = (float*)malloc(num_rows_*num_cols_*sizeof(float));
#pragma acc enter data copyin(this)
#pragma acc enter data create(data_[0:num_rows_*num_cols_])
}
// Copy constructor
Matrix::Matrix(const Matrix &m) :
num_rows_(m.num_rows_),
num_cols_(m.num_cols_)
{
// Use malloc instead of new since new can't be used if Matrix is created inside an acc routine seq function?
// For more info, see https://stackoverflow.com/questions/43497285/openacc-the-c-new-operator-issue
data_ = (float*)malloc(num_rows_*num_cols_*sizeof(float));
#pragma acc enter data copyin(this)
#pragma acc enter data create(data_[0:num_rows_*num_cols_])
#pragma acc parallel loop present(data_[0:num_rows_*num_cols_], m)
for(size_t i = 0; i < num_rows_; ++i) {
for(size_t j = 0; j < num_cols_; ++j) {
(*this)(i,j) = m(i,j);
}
}
}
Matrix::~Matrix() {
#pragma acc exit data delete(data_)
#pragma acc exit data delete(this)
free(data_);
}
// Copy assignment operator
#pragma acc routine seq
Matrix& Matrix::operator=(const Matrix &m) {
if(this == &m){
return *this;
}
for(size_t i = 0; i < this->num_rows_; ++i) {
for(size_t j = 0; j < this->num_cols_; ++j) {
(*this)(i,j) = m(i,j);
}
}
return *this;
}
#pragma acc routine seq
size_t Matrix::num_rows() const {
return num_rows_;
}
#pragma acc routine seq
size_t Matrix::num_cols() const {
return num_cols_;
}
#pragma acc routine seq
float Matrix::operator()(const size_t row, const size_t col) const {
return data_[row*num_cols_ + col];
}
#pragma acc routine seq
float& Matrix::operator()(const size_t row, const size_t col) {
return data_[row*num_cols_ + col];
}
// ERROR SEEMS TO BE OCCURRING HERE!
#pragma acc routine seq
Matrix Matrix::operator*(const Matrix &m2) {
Matrix m3(this->num_rows_, m2.num_cols_);
for(size_t i = 0; i < this->num_rows_; ++i) {
for(size_t j = 0; j < m2.num_cols_; ++j) {
m3(i,j) = 0.0f;
for(size_t k = 0; k < this->num_cols_; ++k) {
m3(i,j) += (*this)(i,k)*m2(k,j);
}
}
}
return m3;
}
int main() {
const size_t num_rows = 4;
const size_t num_cols = 4;
Matrix m1(num_rows,num_cols);
Matrix m2(num_rows,num_cols);
Matrix m3(num_rows,num_cols);
#pragma acc parallel loop present(m1, m2, m3)
for(size_t i = 0; i < num_rows; ++i) {
for(size_t j = 0; j < num_cols; ++j) {
m1(i,j) = 2.5678f;
m2(i,j) = -1.432f;
m3(i,j) = 0.0f;
}
}
#pragma acc kernels present(m1, m2, m3)
{
m3 = m1;
}
return 0;
}
If I run the code while the multiplication operator overload is commented out, then the programs works as expected. However, if I uncomment the multiplication operator overload and run the program again, the program crashes with the following error:
hostptr=0x7ffc99c6cd98,eltsize=24,name=m1,flags=0x200=present,async=-1,threadid=1
FATAL ERROR: data in PRESENT clause was not found on device 1: name=m1 host:0x7ffc99c6cd98
file:/home/jeff/dev/tests/matrix_tests.cpp main line:124
However, the error points to line 124, which is the following:
Matrix m3(num_rows,num_cols);
So I’m at a bit of a loss as to why the program is crashing, especially since multiplication is never used. The compiler I’m using is nvc++ 21.3
and the OS is Ubuntu 18.04
. Any help would be appreciated.