Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
OpenCAC- C++新的操作符问题 在OpenACC常规区域内,C++新操作符似乎是被禁止的。 我想知道为什么我已经检查了常规指令的规范,但我没有在上面找到任何东西_C++_New Operator_Openacc - Fatal编程技术网

OpenCAC- C++新的操作符问题 在OpenACC常规区域内,C++新操作符似乎是被禁止的。 我想知道为什么我已经检查了常规指令的规范,但我没有在上面找到任何东西

OpenCAC- C++新的操作符问题 在OpenACC常规区域内,C++新操作符似乎是被禁止的。 我想知道为什么我已经检查了常规指令的规范,但我没有在上面找到任何东西,c++,new-operator,openacc,C++,New Operator,Openacc,下面是我使用OpenACC实现的代码,这是一个基本的复杂矩阵产品,使用我自己的复数类,我缩小了代码以使其更具可读性: class Complex { private: double* c; public: #pragma acc routine seq Complex ( ) { c = new double[2]; #pragma acc enter data copyin(this) #pragma acc ente

下面是我使用OpenACC实现的代码,这是一个基本的复杂矩阵产品,使用我自己的复数类,我缩小了代码以使其更具可读性:

class Complex {
  private:
    double* c;
  public:
    #pragma acc routine seq
    Complex ( )
    {
      c = new double[2];
      #pragma acc enter data copyin(this)
      #pragma acc enter data create(c[:2])
      c[0] = 0.0;
      c[1] = 0.0;
    }
    Complex ( Complex const& z )
    {
      c = new double[2];
      #pragma acc enter data copyin(this)
      #pragma acc enter data create(c[:2])
      c[0] = z.c[0];
      c[1] = z.c[1];
    }
    ~Complex ( )
    {
      #pragma acc exit data delete(c[:2])
      #pragma acc exit data delete(this)
      delete[] c;
    }
    #pragma acc routine seq
    Complex& operator= ( Complex const z )
    {
      c[0] = z.c[0];
      c[1] = z.c[1];
      return *this;
    }
    #pragma acc routine seq
    Complex& operator+= ( Complex const z )
    {
      c[0] += z.c[0];
      c[1] += z.c[1];
      return *this;
    }
    #pragma acc routine seq
    Complex& operator*= ( Complex const z )
    {
      double a(c[0]), b(c[1]);
      c[0] = a*z.c[0] - b*z.c[1];
      c[1] = b*z.c[0] + a*z.c[1];
      return *this;
    }
};
#pragma acc routine seq
inline Complexe operator* ( Complex z1, Complex const z2 )
{
  z1 *= z2;
  return z1;
}

int main ( )
{
  Complex A[N][N];
  Complex B[N][N];
  // initialisation of A and B
  Complex C[N][N];
  #pragma acc data copyout(C[:N]) copyin(A[:N],B[:N])
  {
    #pragma acc parallel loop
    for (unsigned int i = 0; i < N; i++)
    {
      #pragma acc loop
      for (unsigned int j = 0; j < N; j++)
      {
        Complex accum;
        #pragma acc loop seq
        for (unsigned int j = 0; j < N; j++)
        {
          accum += A[i][k]*B[k][j];
        }
        C[i][j] = accum;
      }
    }
  }
}
我读到new调用了_Znam过程


因此,我想知道为什么不能在OpenACC区域内使用new,以及如何更改代码以避免此问题?

在大多数情况下,OpenACC标准没有指定对特定语言功能的支持。这取决于实现,并取决于目标设备。对于PGI针对NVIDIA GPU的OpenACC实施,不,OpenACC计算区域内不支持新的。malloc是受支持的,但我强烈建议不要从设备代码中动态分配数据。除了拥有相对较小的堆(当前默认值为8MB,但可以使用环境变量PGI_ACC_CUDA_HEAPSIZE将堆增加到32MB)之外,拥有数千个线程分配数据可能会导致严重的性能降低

下面我使用固定大小的数据成员和动态数据成员更新了您的示例。除了修复一些打字错误外,我还从构造函数/析构函数中删除了数据指令,因为数据指令只能在宿主代码中使用。当使用固定大小的数据成员时,代码是直接的。对于动态数据成员,需要附加每个单独的数据成员,即需要在设备对象中设置成员的设备地址。OpenACC标准委员会正在研究一种自动完成这项工作的方法,但目前它需要在程序本身中完成。下面使用的方法,也称为手动深度复制,是PGI扩展,将在下一个OpenACC标准2.6中采用

测试1固定大小数据成员:

#include <iostream>
#ifdef _OPENACC
#include <openacc.h>
#endif
#ifndef N
#define N 32
#endif

class Complex {
  private:
    double c[2];
  public:
    #pragma acc routine seq
    Complex ( )
    {
      c[0] = 0.0;
      c[1] = 0.0;
    }
    Complex ( Complex const& z )
    {
      c[0] = z.c[0];
      c[1] = z.c[1];
    }
    ~Complex ( )
    {
    }
    #pragma acc routine seq
    Complex& operator= ( Complex const z )
    {
      c[0] = z.c[0];
      c[1] = z.c[1];
      return *this;
    }
    #pragma acc routine seq
    Complex& operator+= ( Complex const z )
    {
      c[0] += z.c[0];
      c[1] += z.c[1];
      return *this;
    }
    #pragma acc routine seq
    Complex& operator*= ( Complex const z )
    {
      double a(c[0]), b(c[1]);
      c[0] = a*z.c[0] - b*z.c[1];
      c[1] = b*z.c[0] + a*z.c[1];
      return *this;
    }
    void printme() {
       std::cout << c[0] << ":" << c[1] << std::endl;
    }

};
#pragma acc routine seq
inline Complex operator* ( Complex z1, Complex const z2 )
{
  z1 *= z2;
  return z1;
}

int main ( )
{
  Complex A[N][N];
  Complex B[N][N];
  // initialisation of A and B
  Complex C[N][N];
  #pragma acc data copyout(C[:N]) copyin(A[:N],B[:N])
  {
    #pragma acc parallel loop
    for (unsigned int i = 0; i < N; i++)
    {
      #pragma acc loop
      for (unsigned int j = 0; j < N; j++)
      {
        Complex accum;
        #pragma acc loop seq
        for (unsigned int k = 0; k < N; k++)
        {
          accum += A[i][k]*B[k][j];
        }
        C[i][j] = accum;
      }
    }
  }
  C[0][0].printme();
}
测试2动态数据成员

#include <iostream>
#ifdef _OPENACC
#include <openacc.h>
#endif
#ifndef N
#define N 32
#endif

class Complex {
  private:
    double *c;
  public:
    #pragma acc routine seq
    Complex ( )
    {
      c = (double*) malloc(sizeof(double)*2);
      c[0] = 0.0;
      c[1] = 0.0;
    }
    Complex ( Complex const& z )
    {
      c = (double*) malloc(sizeof(double)*2);
      c[0] = z.c[0];
      c[1] = z.c[1];
    }
    ~Complex ( )
    {
      free(c);
    }
    #pragma acc routine seq
    Complex& operator= ( Complex const z )
    {
      c[0] = z.c[0];
      c[1] = z.c[1];
      return *this;
    }
    #pragma acc routine seq
    Complex& operator+= ( Complex const z )
    {
      c[0] += z.c[0];
      c[1] += z.c[1];
      return *this;
    }
    #pragma acc routine seq
    Complex& operator*= ( Complex const z )
    {
      double a(c[0]), b(c[1]);
      c[0] = a*z.c[0] - b*z.c[1];
      c[1] = b*z.c[0] + a*z.c[1];
      return *this;
    }
    void printme() {
       std::cout << c[0] << ":" << c[1] << std::endl;
    }
#ifdef _OPENACC
    void acc_create() {
        #pragma acc enter data create(c[0:2])
    }
    void acc_copyin() {
        #pragma acc enter data copyin(c[0:2])
    }
    void acc_delete() {
        #pragma acc exit data delete(c)
    }
    void acc_copyout() {
        #pragma acc exit data copyout(c[0:2])
    }
#endif
};
#pragma acc routine seq
inline Complex operator* ( Complex z1, Complex const z2 )
{
  z1 *= z2;
  return z1;
}

int main ( )
{
  Complex A[N][N];
  Complex B[N][N];
  // initialisation of A and B
  Complex C[N][N];

#ifdef _OPENACC
    #pragma acc enter data create(A[0:N][0:N],B[0:N][0:N],C[0:N][0:N])
    for (unsigned int i = 0; i < N; i++)
    {
      for (unsigned int j = 0; j < N; j++) {
           A[i][j].acc_copyin();
           B[i][j].acc_copyin();
           C[i][j].acc_create();
      }
    }
#endif

    #pragma acc parallel loop present(A,B,C)
    for (unsigned int i = 0; i < N; i++)
    {
      #pragma acc loop
      for (unsigned int j = 0; j < N; j++)
      {
        Complex accum;
        #pragma acc loop seq
        for (unsigned int k = 0; k < N; k++)
        {
          accum += A[i][k]*B[k][j];
        }
        C[i][j] = accum;
      }
  }
#ifdef _OPENACC
    for (unsigned int i = 0; i < N; i++)
    {
      for (unsigned int j = 0; j < N; j++) {
           A[i][j].acc_delete();
           B[i][j].acc_delete();
           C[i][j].acc_copyout();
      }
    }
    #pragma acc exit data delete(A[0:N][0:N],B[0:N][0:N],C[0:N][0:N])
#endif
  C[0][0].printme();
}

在大多数情况下,OpenACC标准没有指定对特定语言功能的支持。这取决于实现,并取决于目标设备。对于PGI针对NVIDIA GPU的OpenACC实施,不,OpenACC计算区域内不支持新的。malloc是受支持的,但我强烈建议不要从设备代码中动态分配数据。除了拥有相对较小的堆(当前默认值为8MB,但可以使用环境变量PGI_ACC_CUDA_HEAPSIZE将堆增加到32MB)之外,拥有数千个线程分配数据可能会导致严重的性能降低

下面我使用固定大小的数据成员和动态数据成员更新了您的示例。除了修复一些打字错误外,我还从构造函数/析构函数中删除了数据指令,因为数据指令只能在宿主代码中使用。当使用固定大小的数据成员时,代码是直接的。对于动态数据成员,需要附加每个单独的数据成员,即需要在设备对象中设置成员的设备地址。OpenACC标准委员会正在研究一种自动完成这项工作的方法,但目前它需要在程序本身中完成。下面使用的方法,也称为手动深度复制,是PGI扩展,将在下一个OpenACC标准2.6中采用

测试1固定大小数据成员:

#include <iostream>
#ifdef _OPENACC
#include <openacc.h>
#endif
#ifndef N
#define N 32
#endif

class Complex {
  private:
    double c[2];
  public:
    #pragma acc routine seq
    Complex ( )
    {
      c[0] = 0.0;
      c[1] = 0.0;
    }
    Complex ( Complex const& z )
    {
      c[0] = z.c[0];
      c[1] = z.c[1];
    }
    ~Complex ( )
    {
    }
    #pragma acc routine seq
    Complex& operator= ( Complex const z )
    {
      c[0] = z.c[0];
      c[1] = z.c[1];
      return *this;
    }
    #pragma acc routine seq
    Complex& operator+= ( Complex const z )
    {
      c[0] += z.c[0];
      c[1] += z.c[1];
      return *this;
    }
    #pragma acc routine seq
    Complex& operator*= ( Complex const z )
    {
      double a(c[0]), b(c[1]);
      c[0] = a*z.c[0] - b*z.c[1];
      c[1] = b*z.c[0] + a*z.c[1];
      return *this;
    }
    void printme() {
       std::cout << c[0] << ":" << c[1] << std::endl;
    }

};
#pragma acc routine seq
inline Complex operator* ( Complex z1, Complex const z2 )
{
  z1 *= z2;
  return z1;
}

int main ( )
{
  Complex A[N][N];
  Complex B[N][N];
  // initialisation of A and B
  Complex C[N][N];
  #pragma acc data copyout(C[:N]) copyin(A[:N],B[:N])
  {
    #pragma acc parallel loop
    for (unsigned int i = 0; i < N; i++)
    {
      #pragma acc loop
      for (unsigned int j = 0; j < N; j++)
      {
        Complex accum;
        #pragma acc loop seq
        for (unsigned int k = 0; k < N; k++)
        {
          accum += A[i][k]*B[k][j];
        }
        C[i][j] = accum;
      }
    }
  }
  C[0][0].printme();
}
测试2动态数据成员

#include <iostream>
#ifdef _OPENACC
#include <openacc.h>
#endif
#ifndef N
#define N 32
#endif

class Complex {
  private:
    double *c;
  public:
    #pragma acc routine seq
    Complex ( )
    {
      c = (double*) malloc(sizeof(double)*2);
      c[0] = 0.0;
      c[1] = 0.0;
    }
    Complex ( Complex const& z )
    {
      c = (double*) malloc(sizeof(double)*2);
      c[0] = z.c[0];
      c[1] = z.c[1];
    }
    ~Complex ( )
    {
      free(c);
    }
    #pragma acc routine seq
    Complex& operator= ( Complex const z )
    {
      c[0] = z.c[0];
      c[1] = z.c[1];
      return *this;
    }
    #pragma acc routine seq
    Complex& operator+= ( Complex const z )
    {
      c[0] += z.c[0];
      c[1] += z.c[1];
      return *this;
    }
    #pragma acc routine seq
    Complex& operator*= ( Complex const z )
    {
      double a(c[0]), b(c[1]);
      c[0] = a*z.c[0] - b*z.c[1];
      c[1] = b*z.c[0] + a*z.c[1];
      return *this;
    }
    void printme() {
       std::cout << c[0] << ":" << c[1] << std::endl;
    }
#ifdef _OPENACC
    void acc_create() {
        #pragma acc enter data create(c[0:2])
    }
    void acc_copyin() {
        #pragma acc enter data copyin(c[0:2])
    }
    void acc_delete() {
        #pragma acc exit data delete(c)
    }
    void acc_copyout() {
        #pragma acc exit data copyout(c[0:2])
    }
#endif
};
#pragma acc routine seq
inline Complex operator* ( Complex z1, Complex const z2 )
{
  z1 *= z2;
  return z1;
}

int main ( )
{
  Complex A[N][N];
  Complex B[N][N];
  // initialisation of A and B
  Complex C[N][N];

#ifdef _OPENACC
    #pragma acc enter data create(A[0:N][0:N],B[0:N][0:N],C[0:N][0:N])
    for (unsigned int i = 0; i < N; i++)
    {
      for (unsigned int j = 0; j < N; j++) {
           A[i][j].acc_copyin();
           B[i][j].acc_copyin();
           C[i][j].acc_create();
      }
    }
#endif

    #pragma acc parallel loop present(A,B,C)
    for (unsigned int i = 0; i < N; i++)
    {
      #pragma acc loop
      for (unsigned int j = 0; j < N; j++)
      {
        Complex accum;
        #pragma acc loop seq
        for (unsigned int k = 0; k < N; k++)
        {
          accum += A[i][k]*B[k][j];
        }
        C[i][j] = accum;
      }
  }
#ifdef _OPENACC
    for (unsigned int i = 0; i < N; i++)
    {
      for (unsigned int j = 0; j < N; j++) {
           A[i][j].acc_delete();
           B[i][j].acc_delete();
           C[i][j].acc_copyout();
      }
    }
    #pragma acc exit data delete(A[0:N][0:N],B[0:N][0:N],C[0:N][0:N])
#endif
  C[0][0].printme();
}

你到底为什么用双*c;而不是双r;和双i;对于实部和虚部?目前,您必须自己实现复制构造函数、赋值运算符和c。你也可以把你的电脑扔出窗外。Complex::c会是指向双精度[2]以外的东西的指针吗?那么为什么要使用指针和动态分配呢?事实上,^这并不能回答问题,但你在这里使用动态分配完全是愚蠢的。在我看来,这个问题与新的运算符无关,而是与调用pgc++编译器的方式有关,这并没有正确地引入C++标准库。在进行诊断/研究时,不要急于下结论。不是真的。不,我只是在谷歌上搜索了一下,浏览了前几个项目。你到底为什么使用double*c;而不是双r;和双i;对于实部和虚部?目前,您必须自己实现复制构造函数、赋值运算符和c。你也可以把你的电脑扔出窗外。Complex::c会是指向双精度[2]以外的东西的指针吗?那么为什么要使用指针和动态分配呢?事实上,^这并不能回答问题,但你在这里使用动态分配完全是愚蠢的。在我看来,这个问题与新的运算符无关,而是与调用pgc++编译器的方式有关,这并没有正确地引入C++标准库。表现出色时不要急于下结论
我只是在谷歌上搜索了一下,浏览了前几个项目。这正是我想知道的,非常感谢!太好了,这正是我想知道的,非常感谢!