2012-10-07 9 views
6

मैं, CUDA के साथ एक अजीब समस्याpycuda लगता nondeterministic

नीचे स्निपेट में,

#include <stdio.h> 

#define OUTPUT_SIZE   26 

typedef $PRECISION REAL; 

extern "C"  
{ 
    __global__ void test_coeff (REAL* results) 
    { 
     int id  = blockDim.x * blockIdx.x + threadIdx.x; 

     int out_index = OUTPUT_SIZE * id; 
     for (int i=0; i<OUTPUT_SIZE; i++) 
     {    
      results[out_index+i]=id; 
      printf("q"); 
     } 
    } 
} 

जब मैं संकलन और कोड (pycuda के माध्यम से) चलाने के लिए, यह उम्मीद के रूप में काम करता है मिल गया है। जब मैं printf को हटाता हूं, तो परिणाम अजीब होते हैं - अधिकांश सरणी सही ढंग से आबादी में होती है, लेकिन उनमें से कुछ पूरी तरह से यादृच्छिक लगती है। , बिना यह यह कुछ यादृच्छिक त्रुटि (2452 के आसपास मेरी मशीन पर (अधिकतम के लिए प्रिंट) -

import numpy as np 
import string 

#pycuda stuff 
import pycuda.driver as drv 
import pycuda.autoinit 

from pycuda.compiler import SourceModule 

class MC: 

    cudacodetemplate = """ 
    #include <stdio.h> 

    #define OUTPUT_SIZE   26 

    typedef $PRECISION REAL; 

    extern "C"  
    { 
     __global__ void test_coeff (REAL* results) 
     { 
      int id  = blockDim.x * blockIdx.x + threadIdx.x; 

      int out_index = OUTPUT_SIZE * id; 
      for (int i=0; i<OUTPUT_SIZE; i++) 
      {    
       results[out_index+i]=id; 
       //printf("q"); 
      } 
     } 
    } 
    """ 

    def __init__(self, size, prec = np.float32): 
     #800 meg should be enough . . . 
     drv.limit.MALLOC_HEAP_SIZE = 1024*1024*800 

     self.size  = size 
     self.prec  = prec 
     template  = string.Template(MC.cudacodetemplate) 
     self.cudacode = template.substitute(PRECISION = 'float' if prec==np.float32 else 'double') 

     #self.module  = pycuda.compiler.SourceModule(self.cudacode, no_extern_c=True, options=['--ptxas-options=-v']) 
     self.module  = SourceModule(self.cudacode, no_extern_c=True) 

    def test(self, out_size): 
     #try to precalc the co-efficients for just the elements of the vector that changes 
     test = np.zeros((128, out_size*(2**self.size)), dtype=self.prec) 
     test2 = np.zeros((128, out_size*(2**self.size)), dtype=self.prec) 

     test_coeff = self.module.get_function ('test_coeff') 
     test_coeff(drv.Out(test), block=(2**self.size,1,1), grid=(128, 1)) 
     test_coeff(drv.Out(test2), block=(2**self.size,1,1), grid=(128, 1)) 
     error = (test-test2) 
     return error 

if __name__ == '__main__': 
    p1 = MC (5, np.float64) 
    err = p1.test(26) 
    print err.max() 
    print err.min() 

असल में, कर्नेल में printf के साथ, अरे है 0:

यहाँ पूर्ण अजगर कोड है और -2583 (मिनट के लिए))

मुझे नहीं पता कि क्यों।

मैं एक GeForce 570

धन्यवाद के साथ pycuda पर CUDA 4.2 चलाने गए 2012.2 (विंडोज 7 64 बिट)।

+0

क्षमा करें, लेकिन मैं इसे 64 लिनक्स होस्ट और जीटीएक्स 670 पर CUDA 4.2 का उपयोग करके पुन: उत्पन्न नहीं कर सकता। प्रत्येक बार जब मैं इसे पोस्ट करता हूं तो कर्नेल का उपयोग करके उन्हें चलाने के लिए एकल और डबल सटीक संस्करण दोनों पास होते हैं। – talonmies

+0

मुझे लगता है कि मेरे पास दोषपूर्ण हार्डवेयर है - हालांकि मुझे यकीन नहीं है कि 4.2 जीपीयू एसडीके में अन्य सभी कूडा कार्यक्रम ठीक क्यों काम करते हैं। मैं इसे लिनक्स में उसी हार्डवेयर के साथ चलाने का प्रयास करूंगा - फिर मैं विंडोज़ में विभिन्न हार्डवेयर आज़माउंगा और देखूंगा। । । – user1726633

+0

मुझे पिकुडा नहीं पता, लेकिन सी/सी ++ में आप '__global__' या' __device__' कोड के अंदर 'printf' फ़ंक्शन का उपयोग नहीं कर सकते हैं। क्या यह पिकुडा के साथ संभव है? – szamil

उत्तर

1

यह संकलक अनुकूलन के कारण सबसे अधिक संभावना है। आप आईडी के लूप-निरंतर मान की लंबाई में स्मृति OUTPUT_SIZE की एक ब्लॉक सेट कर रहे हैं। मेरे अनुभव में संकलक एक memcpy या whathaveyou को ऑप्टिमाइज़ करेगा जब तक लूप में कुछ और चल रहा है - यानी आपका प्रिंट स्टेटमेंट। इसके अलावा, अगर आप स्मृति के उस ब्लॉक का उपयोग नहीं करते हैं तो संकलक पूरे लूप को अनुकूलित कर सकता है। अपने अनुकूलन स्तरों के साथ झुकाव का प्रयास करें और देखें कि आपके पास अलग-अलग परिणाम हैं या नहीं।

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