2012-11-15 12 views
8

के बीच अंतर करते हैंPyopencl: to_device और बफर

import pyopencl as cl 
import pyopencl.array as cl_array 
import numpy 
a = numpy.random.rand(50000).astype(numpy.float32) 
mf = cl.mem_flags 

a_gpu = cl.Buffer(self.ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=a) 

और

a_gpu = cl_array.to_device(self.ctx, self.queue, a) 

के बीच क्या अंतर है?

और

result = numpy.empty_like(a) 
cl.enqueue_copy(self.queue, result, result_gpu) 

और

result = result_gpu.get() 

के बीच क्या अंतर है?

उत्तर

16

बफर malloc का सीएल का संस्करण है, जबकि pyopencl.array.Array गणना डिवाइस पर numpy arrays का एक कामकाज है।

तो अपने प्रश्न के पहले भाग के दूसरे संस्करण के लिए, आप a_gpu + 2 लिख सकते हैं ताकि आपके सरणी में प्रत्येक नंबर में 2 जोड़े गए हों, जबकि Buffer के मामले में, PyOpenCL केवल एक बैग देखता है बाइट्स का और ऐसा कोई ऑपरेशन नहीं कर सकता है।

आपके प्रश्न का दूसरा भाग विपरीत में समान है: यदि आपके पास PyOpenCL सरणी है, तो .get() डेटा को प्रतिलिपि बनाता है और इसे एक (होस्ट-आधारित) numpy सरणी में परिवर्तित करता है। चूंकि numpy arrays Python में संगत स्मृति प्राप्त करने के अधिक सुविधाजनक तरीकों में से एक है, enqueue_copy के साथ दूसरा संस्करण भी एक numpy सरणी में समाप्त होता है - लेकिन ध्यान दें कि आप इस डेटा को किसी भी आकार की सरणी में कॉपी कर सकते थे (लंबे समय तक क्योंकि यह काफी बड़ा है) और किसी भी प्रकार - प्रतिलिपि बाइट्स के बैग के रूप में की जाती है, जबकि .get() सुनिश्चित करता है कि आप एक ही आकार प्राप्त करें और होस्ट पर टाइप करें।

बोनस तथ्य: निश्चित रूप से प्रत्येक पाओपेनसीएल सरणी अंतर्निहित एक बफर है। आप इसे .data विशेषता से प्राप्त कर सकते हैं।

+4

मुझे अभी एहसास हुआ है कि आप PyOpenCL के लेखक हैं। PyOpenCL के लिए और आपके उत्तर के लिए बहुत बहुत धन्यवाद! – petRUShka

3

पहले प्रश्न का उत्तर देने के लिए, Buffer(hostbuf=...) को buffer interface (reference) लागू करने वाले किसी भी चीज़ के साथ बुलाया जा सकता है। pyopencl.array.to_device(...) को ndarray (reference) के साथ कॉल किया जाना चाहिए। ndarray बफर इंटरफ़ेस लागू करता है और किसी भी स्थान पर काम करता है। हालांकि, केवल hostbuf=... उदाहरण के लिए काम करने की उम्मीद की जाएगी उदाहरण के लिए bytearray (जो बफर इंटरफेस को भी लागू करता है)। मैंने इसकी पुष्टि नहीं की है, लेकिन ऐसा लगता है कि दस्तावेज़ क्या सुझाव देते हैं।

दूसरा सवाल पर, मुझे यकीन है कि नहीं किस प्रकार result_gpu होने के लिए जब आप इसे पर get() (आप Buffer.get_host_array() मतलब था?) कहते हैं जो भी हो, Buffer, Image और host के संयोजन के बीच enqueue_copy() काम करता है माना जाता है हूँ, हो सकता है ऑफसेट और क्षेत्र, और एसिंक्रोनस (is_blocking=False के साथ) हो सकता है, और मुझे लगता है कि ये क्षमताओं केवल इस तरह उपलब्ध हैं (जबकि get() अवरुद्ध हो जाएगा और पूरे बफर को वापस कर देगा)। (reference)

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