दिलचस्प पोस्ट
वर्तमान फ़ाइल का नाम gulp.src में प्राप्त करें () SQL में तालिका का अंतिम रिकॉर्ड कैसे चुनूं? SQL सर्वर 2005 से डेटा को MySQL से निर्यात कैसे करें मैं डॉकर कंटेनर के लिए पर्यावरण चर कैसे पार करूं? jQuery डेटा बनाम एटआर? Urlib और अजगर के माध्यम से एक चित्र डाउनलोड करना धाराप्रवाह Nhibernate से XML मैपिंग उत्पन्न करें किस प्रकार का आभासी मशीन बीआम (एर्लंग वीएम) है? सी में संरचनाओं में पैडिंग जब सी ++ कंपाइलर्स ने स्ट्रिंग में दो हेक्स अंक से अधिक वर्णों को अक्षरशः चरित्र बचाना शुरू किया था? एक चुनिंदा ड्रॉप डाउन से jQuery शो / छुपा विकल्प, जब अन्य चुनिंदा ड्रॉपडाउन पर विकल्प चुना जाता है एक सॉकेट तक पहुंचने के लिए एक प्रयास किया गया था, जिसने इसकी पहुंच अनुमतियों से मना किया लोकलहोस्ट के बजाए आईपी पता के साथ वेब साइट को ब्राउज़ करें पूर्णस्क्रीन में एंड्रॉइड-वीडियो देखें एमवीवीएम के साथ डब्ल्यूपीएफ में संवाद के लिए अच्छा या बुरा अभ्यास?

क्यूडा कर्नेल को 3 डी सरणी भेजना

मैं एक उत्तर के रूप में दिए गए कोड को लेता हूं, मैं दो 2 डी (खड़ा हुआ) सरणियों को नेस्टेड लूप के प्रयोग से कैसे जोड़ सकता हूं? और इसे 2 डी के बजाय 3 डी के लिए उपयोग करने का प्रयास किया और अन्य हिस्सों को थोड़ा बदल दिया, अब यह इस प्रकार दिखता है:

__global__ void doSmth(int*** a) { for(int i=0; i<2; i++) for(int j=0; j<2; j++) for(int k=0; k<2; k++) a[i][j][k]=i+j+k; } int main() { int*** h_c = (int***) malloc(2*sizeof(int**)); for(int i=0; i<2; i++) { h_c[i] = (int**) malloc(2*sizeof(int*)); for(int j=0; j<2; j++) GPUerrchk(cudaMalloc((void**)&h_c[i][j],2*sizeof(int))); } int*** d_c; GPUerrchk(cudaMalloc((void****)&d_c,2*sizeof(int**))); GPUerrchk(cudaMemcpy(d_c,h_c,2*sizeof(int**),cudaMemcpyHostToDevice)); doSmth<<<1,1>>>(d_c); GPUerrchk(cudaPeekAtLastError()); int res[2][2][2]; for(int i=0; i<2; i++) for(int j=0; j<2; j++) GPUerrchk(cudaMemcpy(&res[i][j][0], h_c[i][j],2*sizeof(int),cudaMemcpyDeviceToHost)); for(int i=0; i<2; i++) for(int j=0; j<2; j++) for(int k=0; k<2; k++) printf("[%d][%d][%d]=%d\n",i,j,k,res[i][j][k]); } 

उपरोक्त कोड में मैं 2 का उपयोग ह्कका प्रत्येक आयाम के लिए आकार के रूप में करता हूं, वास्तविक क्रियान्वयन में इन आकारों को बहुत बड़ी संख्या में और अलग-अलग हिस्सों में "पूर्णांक" या अधिक आयामों के उप-नियमों के प्रत्येक भाग के लिए रखना होगा I । कर्नेल कॉल के बाद मुझे इस भाग के साथ समस्या हो रही है, जहां मैं रिज़ ऑरेंज के परिणामों को कॉपी करने की कोशिश करता हूं। क्या आप मुझे समस्या ठीक करने में सहायता कर सकते हैं? प्लज़ आप जिस तरह से मैं इसे ऊपर लिख रहा हूँ उसमें समाधान दिखा सकता है धन्यवाद!

Solutions Collecting From Web of "क्यूडा कर्नेल को 3 डी सरणी भेजना"

सबसे पहले, मुझे लगता है कि जब आप पिछले प्रश्न के जवाब में तैनात हैं, तो वह प्रतिभाशाली है, जो कि अच्छा कोडिंग का प्रतिनिधित्व करने का इरादा नहीं था तो यह जानने के लिए कि कैसे इसे 3 डी में विस्तारित किया जाए, हो सकता है कि आपके समय का सबसे अच्छा उपयोग न हो। उदाहरण के लिए, हम प्रोग्राम लिखना क्यों चाहते हैं जो बिल्कुल एक थ्रेड का उपयोग करते हैं? हालांकि इस तरह के कर्नेल का वैध उपयोग हो सकता है, लेकिन यह उनमें से एक नहीं है। आपके कर्नेल में समानांतर में स्वतंत्र कार्य का एक गुच्छा होने की संभावना है, लेकिन इसके बजाय आप इसे एक धागे पर मजबूर कर रहे हैं, और इसे क्रमबद्ध कर रहे हैं। समानांतर कार्य की परिभाषा है:

 a[i][j][k]=i+j+k; 

चलो यह समझते हैं कि GPU पर समानांतर कैसे संभालना है

मैं एक अन्य परिचयात्मक अवलोकन करना चाहूंगा, क्योंकि हम उन समस्याओं से निपट रहे हैं जिनके आकार में समय से पहले जाना जाता है, चलो सी से इसका फायदा उठाने के लिए उपयोग करें क्योंकि हम भाषा से प्राप्त कर सकते हैं। नेस्टेड लूप को करने के लिए कुछ मामलों में cudaMalloc की आवश्यकता हो सकती है, लेकिन मुझे नहीं लगता कि यह उनमें से एक है।

यह एक ऐसा कोड है जो काम समानांतर में पूरा करता है:

 #include <stdio.h> #include <stdlib.h> // set a 3D volume // To compile it with nvcc execute: nvcc -O2 -o set3d set3d.cu //define the data set size (cubic volume) #define DATAXSIZE 100 #define DATAYSIZE 100 #define DATAZSIZE 20 //define the chunk sizes that each threadblock will work on #define BLKXSIZE 32 #define BLKYSIZE 4 #define BLKZSIZE 4 // for cuda error checking #define cudaCheckErrors(msg) \ do { \ cudaError_t __err = cudaGetLastError(); \ if (__err != cudaSuccess) { \ fprintf(stderr, "Fatal error: %s (%s at %s:%d)\n", \ msg, cudaGetErrorString(__err), \ __FILE__, __LINE__); \ fprintf(stderr, "*** FAILED - ABORTING\n"); \ return 1; \ } \ } while (0) // device function to set the 3D volume __global__ void set(int a[][DATAYSIZE][DATAXSIZE]) { unsigned idx = blockIdx.x*blockDim.x + threadIdx.x; unsigned idy = blockIdx.y*blockDim.y + threadIdx.y; unsigned idz = blockIdx.z*blockDim.z + threadIdx.z; if ((idx < (DATAXSIZE)) && (idy < (DATAYSIZE)) && (idz < (DATAZSIZE))){ a[idz][idy][idx] = idz+idy+idx; } } int main(int argc, char *argv[]) { typedef int nRarray[DATAYSIZE][DATAXSIZE]; const dim3 blockSize(BLKXSIZE, BLKYSIZE, BLKZSIZE); const dim3 gridSize(((DATAXSIZE+BLKXSIZE-1)/BLKXSIZE), ((DATAYSIZE+BLKYSIZE-1)/BLKYSIZE), ((DATAZSIZE+BLKZSIZE-1)/BLKZSIZE)); // overall data set sizes const int nx = DATAXSIZE; const int ny = DATAYSIZE; const int nz = DATAZSIZE; // pointers for data set storage via malloc nRarray *c; // storage for result stored on host nRarray *d_c; // storage for result computed on device // allocate storage for data set if ((c = (nRarray *)malloc((nx*ny*nz)*sizeof(int))) == 0) {fprintf(stderr,"malloc1 Fail \n"); return 1;} // allocate GPU device buffers cudaMalloc((void **) &d_c, (nx*ny*nz)*sizeof(int)); cudaCheckErrors("Failed to allocate device buffer"); // compute result set<<<gridSize,blockSize>>>(d_c); cudaCheckErrors("Kernel launch failure"); // copy output data back to host cudaMemcpy(c, d_c, ((nx*ny*nz)*sizeof(int)), cudaMemcpyDeviceToHost); cudaCheckErrors("CUDA memcpy failure"); // and check for accuracy for (unsigned i=0; i<nz; i++) for (unsigned j=0; j<ny; j++) for (unsigned k=0; k<nx; k++) if (c[i][j][k] != (i+j+k)) { printf("Mismatch at x= %d, y= %d, z= %d Host= %d, Device = %d\n", i, j, k, (i+j+k), c[i][j][k]); return 1; } printf("Results check!\n"); free(c); cudaFree(d_c); cudaCheckErrors("cudaFree fail"); return 0; } 

चूंकि आपने इसे टिप्पणियों में कहा है, यहां यह परिवर्तनों की सबसे छोटी संख्या है जो मैं काम करने के लिए आपके कोड में कर सकता हूं। आइए हम अपने पिछले प्रश्न से आपकी कुछ तूलोनी टिप्पणीों की भी याद दिलाएं:

"कोड की जटिलता और प्रदर्शन के कारणों के लिए, आप वास्तव में ऐसा नहीं करना चाहते हैं, सीयूडीए कोड में पॉइंटरों के एआरएम्स का प्रयोग करना रेखीय मेमोरी का उपयोग करके वैकल्पिक से कहीं ज्यादा कठिन और धीमा है।"

"यह रेखीय स्मृति का उपयोग करने के लिए की तुलना में इस तरह के एक खराब विचार है।"

मुझे यह सुनिश्चित करने के लिए कागज़ पर इस आरेख का उपयोग करना था कि मुझे अपने सभी पॉइंटर को सही प्रतिलिपि मिला।

 #include <cstdio> inline void GPUassert(cudaError_t code, char * file, int line, bool Abort=true) { if (code != 0) { fprintf(stderr, "GPUassert: %s %s %d\n", cudaGetErrorString(code),file,line); if (Abort) exit(code); } } #define GPUerrchk(ans) { GPUassert((ans), __FILE__, __LINE__); } __global__ void doSmth(int*** a) { for(int i=0; i<2; i++) for(int j=0; j<2; j++) for(int k=0; k<2; k++) a[i][j][k]=i+j+k; } int main() { int*** h_c = (int***) malloc(2*sizeof(int**)); for(int i=0; i<2; i++) { h_c[i] = (int**) malloc(2*sizeof(int*)); for(int j=0; j<2; j++) GPUerrchk(cudaMalloc((void**)&h_c[i][j],2*sizeof(int))); } int ***h_c1 = (int ***) malloc(2*sizeof(int **)); for (int i=0; i<2; i++){ GPUerrchk(cudaMalloc((void***)&(h_c1[i]), 2*sizeof(int*))); GPUerrchk(cudaMemcpy(h_c1[i], h_c[i], 2*sizeof(int*), cudaMemcpyHostToDevice)); } int*** d_c; GPUerrchk(cudaMalloc((void****)&d_c,2*sizeof(int**))); GPUerrchk(cudaMemcpy(d_c,h_c1,2*sizeof(int**),cudaMemcpyHostToDevice)); doSmth<<<1,1>>>(d_c); GPUerrchk(cudaPeekAtLastError()); int res[2][2][2]; for(int i=0; i<2; i++) for(int j=0; j<2; j++) GPUerrchk(cudaMemcpy(&res[i][j][0], h_c[i][j],2*sizeof(int),cudaMemcpyDeviceToHost)); for(int i=0; i<2; i++) for(int j=0; j<2; j++) for(int k=0; k<2; k++) printf("[%d][%d][%d]=%d\n",i,j,k,res[i][j][k]); } 

संक्षेप में, हमें निम्न क्रम को करना होगा:

  1. मॉलोक एक बहुआयामी सरणी (मेजबान पर), समस्या के आकार से कम एक आयाम, आखिरी आयाम को संकेतक के एक समूह के रूप में सेट किया जाता है जो क्यूडम मैलॉक ने मेजबान के बजाय डिवाइस पर किया था।
  2. एक दूसरे के बहुआयामी सरणी को एक समान वर्ग के बनाओ, जैसा कि पिछले चरण में बनाया गया था, लेकिन पिछले चरण में बनाए गए से कम एक आयाम। इस सरणी को डिवाइस पर कूडामॉलोक की अंतिम रैंक भी होना चाहिए।
  3. पिछले चरण में डिवाइस पर cudaMalloced क्षेत्र में दूसरे पिछले चरण से होस्ट पॉइंटर के अंतिम सेट की प्रतिलिपि बनाएँ।
  4. जब तक हम एक एकल (होस्ट) पॉइंटर से बात करते हैं, तब तक दोहराए चरण दोहराते हैं कि पॉइंटर्स के बहुआयामी सरणी को इंगित करते हैं, जो सभी अब उपकरण पर निवासी हैं।