2014-09-06 8 views
7

अगर मैं इस कार्यक्रम मैं त्रुटि "एक अवैध स्मृति पहुँच लाइन 48 पर matrixMulti.cu में सामना करना पड़ा था" चलाते हैं। मैंने खोज की और बहुत कोशिश की। तो मुझे उम्मीद है कि कोई मेरी मदद कर सकता है।सरल CUDA टेस्ट हमेशा साथ त्रुटि "एक अवैध स्मृति पहुँच का सामना करना पड़ा था," विफल रहता है

रेखा 48: हैंडल_एआरआरओआर (cudaMemcpy (सरणी, devarray, एन * एन * आकार (int), cudaMemcpyDeviceToHost));

कार्यक्रम सिर्फ CUDA में प्राप्त करने के लिए है। मैंने मैट्रिक्स गुणा को लागू करने की कोशिश की।

#include <iostream> 
#include<cuda.h> 
#include <stdio.h> 

using namespace std; 

#define HANDLE_ERROR(err) (HandleError(err, __FILE__, __LINE__)) 
void printVec(int** a, int n); 

static void HandleError(cudaError_t err, const char *file, int line) 
{ 
    if (err != cudaSuccess) 
    { 
    printf("%s in %s at line %d\n", cudaGetErrorString(err), 
      file, line); 
    exit(EXIT_FAILURE); 
    } 
} 

void checkCUDAError(const char *msg) 
{ 
    cudaError_t err = cudaGetLastError(); 
    if(cudaSuccess != err) 
    { 
     fprintf(stderr, "Cuda error: %s: %s.\n", msg, 
           cudaGetErrorString(err)); 
     exit(EXIT_FAILURE); 
    }       
} 
__global__ void MatrixMulti(int** a, int** b) { 
    b[0][0]=4; 
} 

int main() { 
    int N =10; 
    int** array, **devarray; 
    array = new int*[N]; 

    for(int i = 0; i < N; i++) { 
     array[i] = new int[N]; 
    } 

    HANDLE_ERROR (cudaMalloc((void**)&devarray, N*N*sizeof(int))); 
    HANDLE_ERROR (cudaMemcpy(devarray, array, N*N*sizeof(int), cudaMemcpyHostToDevice)); 
    MatrixMulti<<<1,1>>>(array,devarray); 
    HANDLE_ERROR (cudaMemcpy(array, devarray, N*N*sizeof(int), cudaMemcpyDeviceToHost)); 
    HANDLE_ERROR (cudaFree(devarray)); 
    printVec(array,N); 

    return 0; 
} 

void printVec(int** a , int n) { 
    for(int i =0 ; i < n; i++) { 
     for (int j = 0; j <n; j++) { 
     cout<< a[i][j] <<" "; 
     }  
     cout<<" "<<endl;  
    } 
} 

उत्तर

9

सामान्यतः, एक दोगुनी-सबस्क्रिप्टेड सी सरणी आवंटित करने और प्रतिलिपि बनाने की आपकी विधि काम नहीं करेगी। cudaMemcpyफ्लैट, समीपवर्ती आवंटित, एकल सूचक, एकल सबस्क्रिप्ट सरणियों की उम्मीद है।

इस भ्रम का एक परिणाम के रूप में संकेत दिए गए अपने कर्नेल (int** a, int** b) करने के लिए पारित किया जा रहा ठीक से (सुरक्षित रूप से) नहीं किया जा सकता दो बार dereferenced:

b[0][0]=4; 

जब आप कर्नेल कोड में ऊपर करने की कोशिश, आप प्राप्त एक अवैध स्मृति पहुंच, क्योंकि आपने डिवाइस पर पॉइंटर-टू-पॉइंटर शैली आवंटन को सही ढंग से आवंटित नहीं किया है।

यदि आप cuda-memcheck के साथ अपने कोड भाग गया, आप कर्नेल कोड में अवैध रूप से स्मृति उपयोग का एक और संकेत मिलेगा।

इन मामलों में सामान्य सुझाव एकल आयाम में अपने 2 डी सरणी को "फ़्लैट" करना है, और 2 डी एक्सेस अनुकरण करने के लिए उचित सूचक या सूचकांक अंकगणित का उपयोग करना है। यह 2 डी सरणियों के आवंटन के लिए संभव है (यानी डबल सबस्क्रिप्ट, डबल-सूचक), लेकिन यह काफी शामिल है (एक "गहरी प्रतिलिपि" के लिए जरूरत के लिए भाग में कारण)। यदि आप इसके बारे में अधिक जानना चाहते हैं तो CUDA 2D array के लिए ऊपरी दाएं कोने पर खोजें।

यहाँ सरणी डिवाइस साइड सरणी के लिए सपाट है कि अपने कोड का एक संस्करण है:

$ cat t60.cu 
#include <iostream> 
#include <cuda.h> 
#include <stdio.h> 

using namespace std; 

#define HANDLE_ERROR(err) (HandleError(err, __FILE__, __LINE__)) 
void printVec(int** a, int n); 

static void HandleError(cudaError_t err, const char *file, int line) 
{ 
    if (err != cudaSuccess) 
    { 
    printf("%s in %s at line %d\n", cudaGetErrorString(err), 
      file, line); 
    exit(EXIT_FAILURE); 
    } 
} 

void checkCUDAError(const char *msg) 
{ 
    cudaError_t err = cudaGetLastError(); 
    if(cudaSuccess != err) 
    { 
     fprintf(stderr, "Cuda error: %s: %s.\n", msg, 
           cudaGetErrorString(err)); 
     exit(EXIT_FAILURE); 
    } 
} 

__global__ void MatrixMulti(int* b, unsigned n) { 
    for (int row = 0; row < n; row++) 
     for (int col=0; col < n; col++) 
    b[(row*n)+col]=col; //simulate 2D access in kernel code 
} 

int main() { 
    int N =10; 
    int** array, *devarray; // flatten device-side array 
    array = new int*[N]; 
    array[0] = new int[N*N]; // host allocation needs to be contiguous 
    for (int i = 1; i < N; i++) array[i] = array[i-1]+N; //2D on top of contiguous allocation 

    HANDLE_ERROR (cudaMalloc((void**)&devarray, N*N*sizeof(int))); 
    HANDLE_ERROR (cudaMemcpy(devarray, array[0], N*N*sizeof(int), cudaMemcpyHostToDevice)); 
    MatrixMulti<<<1,1>>>(devarray, N); 
    HANDLE_ERROR (cudaMemcpy(array[0], devarray, N*N*sizeof(int), cudaMemcpyDeviceToHost)); 
    HANDLE_ERROR (cudaFree(devarray)); 
    printVec(array,N); 

    return 0; 
} 

void printVec(int** a , int n) { 
    for(int i =0 ; i < n; i++) { 
     for (int j = 0; j <n; j++) { 
     cout<< a[i][j] <<" "; 
     } 
     cout<<" "<<endl; 
    } 
} 
$ nvcc -arch=sm_20 -o t60 t60.cu 
$ ./t60 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
$ 
+0

धन्यवाद :) मुझे लगता है कि मैं मैट्रिक्स के -1 डी संस्करण की कोशिश करेंगे, यह आसान हो रहा है – Henrik

संबंधित मुद्दे

 संबंधित मुद्दे