Как использовать один и тот же на стороне девайса и хоста. CUDA
Имеется класс Sequence. Мне нужно сделать так, чтобы все изменения с объектами класса на стороне девайса сохранились на стороне хоста. Я передаю массив объектов Sequence в девайс, там с ним работаю и при попытке вернуть этот массив обратно на хост получаю массив объектов, у которых все значения обнулены(по умолчанию, не измененные). Подскажите, пожалуйста, как сделать так, чтобы все изменения, сделанные на стороне девайса каким-то чудом были сохранены.
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <iostream>
#include <time.h>
using namespace std;
class Sequence {
public:
int getSize() { return size; }
int* getArray() { return arr; }
int getStartNum() { return startNum; }
__device__ __host__ void push_back(int value) {
int *newArr = new int[size + 1];
for (int i = 0; i < size; i++) newArr[i] = arr[i];
newArr[size++] = value;
delete[] this->arr;
this->arr = newArr;
}
__device__ __host__ int getNumByIndex(int index) { return arr[index]; }
//__device__ void incSize() { this->size++; }
__device__ __host__ void setStartNum(int value) { this->startNum = value; }
void printSeq() {
for (int i = 0; i < size; i++) {
if (i == 0) {
cout << arr[i];
continue;
}
cout << "->" << arr[i];
}
cout << "\n\n";
}
private:
int size;
int *arr;
int startNum;
};
int* generateNumbers(int startNum, int endNum) {
int *newArr = new int[endNum - startNum + 1];
for (int i = startNum, int k = 0; i <= endNum; i++, k++)newArr[k] = i;
return newArr;
}
__global__ void generateSequences(Sequence* seqs, int *nums, int size) {
int idx = threadIdx.x;
if (idx < size) {
int n = nums[idx];
Sequence currSeq = seqs[idx];
currSeq.push_back(n);
currSeq.setStartNum(n);
for (int i = 1; currSeq.getNumByIndex(i) != 1; i++) {
n = ((n % 2 == 0) ? (n / 2) : (3 * n + 1));
currSeq.push_back(n);
}
}
}
void main()
{
srand(time(NULL));
int start, end;
cout << "Enter start number: ";
cin >> start;
cout << "Enter final number: ";
cin >> end;
int size = end - start + 1;
Sequence *dev_seqs = 0;
Sequence *pickedSeqs = new Sequence[size];
int *dev_nums = 0;
cudaSetDevice(0);
cudaError_t cudaStatus;
int *numbers = generateNumbers(start, end);
cudaMalloc((void**)&dev_seqs, size * sizeof(Sequence));
cudaMalloc((void**)&dev_nums, size * sizeof(int));
cudaMemcpy(dev_nums, numbers, size * sizeof(int), cudaMemcpyKind::cudaMemcpyHostToDevice);
cudaDeviceSynchronize();
int threadsPerBlock = 1024;
int blocksPerGrid = (size + threadsPerBlock - 1) / threadsPerBlock;
cudaEvent_t startt, stopt;
float time = 1;
cudaEventCreate(&startt);
cudaEventCreate(&stopt);
cudaEventRecord(startt, 0);
//-------------------GPU------------------------------------
generateSequences << <1, size >> >(dev_seqs, dev_nums, size);
//----------------------------------------------------------
cudaEventRecord(stopt, 0);
cudaStatus = cudaEventElapsedTime(&time, startt, stopt);
if (cudaStatus != cudaSuccess) {
printf("\nError 'cudaEventElapsedTime': %s\n\n", cudaGetErrorString(cudaStatus));
}
printf("Time to generate: %3.1f ms \n\n", time);
cudaDeviceSynchronize();
cudaStatus = cudaMemcpy(pickedSeqs, dev_seqs, size * sizeof(Sequence), cudaMemcpyKind::cudaMemcpyDeviceToHost);
if (cudaStatus != cudaSuccess) {
printf("Error 'cudaMemcpy(...,cudaMemcpyKind::cudaMemcpyDeviceToHost)': %s\n\n", cudaGetErrorString(cudaStatus));
}
for (int i = 0; i < size; i++) {
pickedSeqs[i].printSeq();
}
cudaFree(dev_nums);
cudaFree(dev_seqs);
}