2015-08-24 5 views
6

अंदर अनुक्रमण 3 डी सरणियों मैं अजगर में छवियों को संसाधित करने और कर्नेल में एक 3 डी numpy सरणी (height एक्स width एक्स 4) भेजने के लिए PyOpenCL उपयोग कर रहा हूँ। मुझे कर्नेल कोड के अंदर 3 डी सरणी अनुक्रमणित करने में समस्या हो रही है। अभी के लिए मैं केवल प्रति आउटपुट में संपूर्ण इनपुट सरणी की प्रतिलिपि बनाने में सक्षम हूं। वर्तमान कोड ऐसा दिखाई देता है जहां imgimg.shape = (320, 512, 4) साथ छवि है:PyOpenCL कर्नेल कोड

__kernel void part1(__global float* img, __global float* results) 
{ 
    unsigned int x = get_global_id(0); 
    unsigned int y = get_global_id(1); 
    unsigned int z = get_global_id(2); 

    int index = x + 320*y + 320*512*z; 

    results[index] = img[index]; 
} 

हालांकि, मैं काफी यह कैसे काम समझ में नहीं आता। उदाहरण के लिए, मैं इस कर्नेल के अंदर img[1, 2, 3] के पाइथन समकक्ष को कैसे अनुक्रमणित करूं? और आगे, कुछ इंडेक्स को स्टोर करने के लिए results में कौन सा इंडेक्स इस्तेमाल किया जाना चाहिए यदि मैं पाइथन पर परिणाम प्राप्त करते समय results[1, 2, 3] स्थिति में होना चाहता हूं तो मुझे अंक चाहिए?

इस मैं इस अजगर कोड का उपयोग कर रहा चलाने के लिए:

import pyopencl as cl 
import numpy as np 

class OpenCL: 
def __init__(self): 
    self.ctx = cl.create_some_context() 
    self.queue = cl.CommandQueue(self.ctx) 

def loadProgram(self, filename): 
    f = open(filename, 'r') 
    fstr = "".join(f.readlines()) 
    self.program = cl.Program(self.ctx, fstr).build() 

def opencl_energy(self, img): 
    mf = cl.mem_flags 

    self.img = img.astype(np.float32) 

    self.img_buf = cl.Buffer(self.ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=self.img) 
    self.dest_buf = cl.Buffer(self.ctx, mf.WRITE_ONLY, self.img.nbytes) 

    self.program.part1(self.queue, self.img.shape, None, self.img_buf, self.dest_buf) 
    c = np.empty_like(self.img) 
    cl.enqueue_read_buffer(self.queue, self.dest_buf, c).wait() 
    return c 

example = OpenCL() 
example.loadProgram("get_energy.cl") 
image = np.random.rand(320, 512, 4) 
image = image.astype(np.float32) 
results = example.opencl_energy(image) 
print("All items are equal:", (results==image).all()) 
+0

मैंने देखा, कि pyopenCL सीधे सीएल Arrays को इंटरफ़ेस करने में सक्षम होना चाहिए। मैंने फिर भी इंडेक्सिंग सहित ऐसा करने का प्रबंधन नहीं किया। – Dschoni

+0

क्या यह प्रश्न अभी भी प्रासंगिक है? यदि आप कोशिश करने के इच्छुक हैं तो मुझे कुछ दिलचस्प जानकारी मिल सकती है। – jurij

+0

@jurij अब मेरे लिए नहीं। लेकिन अगर आपके पास कुछ मूल्यवान अंतर्दृष्टि हैं, तो उन्हें दूसरों के लिए साझा करने में संकोच न करें, जो एक ही समस्या का सामना कर सकते हैं। – nikicc

उत्तर

0

हालांकि इस opitimal समाधान नहीं है, मैं अजगर में सरणी linearized और 1 डी के रूप में यह भेजा है। कर्नेल कोड में मैंने रैखिक सूचकांक से x, y और z की गणना की। जब Pyhon पर लौटा, मैं इसे वापस मूल आकार में बदल दिया।

+0

मैं इस लाइन के साथ सोच रहा हूं: क्या यह वास्तव में एक बफर के साथ काम करता है? या ऐसा करने में सक्षम होने के लिए आवश्यक एक सरणी है? – Dschoni

0

अद्यतन: OpenCL डॉक्स राज्य (3.5 में), कि

"Memory objects are categorized into two types: buffer objects, and image objects. A buffer 
object stores a one-dimensional collection of elements whereas an image object is used to store a 
two- or three- dimensional texture, frame-buffer or image." 

हां, तो एक बफर हमेशा रैखिक, या linearized के रूप में आप नीचे मेरी नमूना से देख सकते हैं।

import pyopencl as cl 
import numpy as np 


h_a = np.arange(27).reshape((3,3,3)).astype(np.float32) 

ctx = cl.create_some_context() 
queue = cl.CommandQueue(ctx) 

mf = cl.mem_flags 
d_a = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=h_a) 

prg = cl.Program(ctx, """ 
__kernel void p(__global const float *d_a) { 
    printf("Array element is %f ",d_a[10]); 
} 
""").build() 

prg.p(queue, (1,), None, d_a) 

मुझे

"Array element is 10" 
आउटपुट के रूप में

देता है। तो, बफर वास्तव में रैखिक सरणी है। फिर भी, बेवकूफ [x, y, z] numpy से ज्ञात दृष्टिकोण इस तरह से काम नहीं करता है। एक बफर के बजाय 2 या 3-डी छवि का उपयोग करना चाहिए फिर भी काम करना चाहिए।

-1

मुझे एक ही समस्या का सामना करना पड़ा। https://lists.tiker.net/pipermail/pyopencl/2009-October/000134.html एक साधारण उदाहरण है जो मेरे लिए काम करने वाले PyOpenCL के साथ 3 डी एरे का उपयोग कैसे करें। मैं यहां भविष्य के संदर्भ के लिए कोड उद्धृत करता हूं:

import pyopencl as cl 
import numpy 
import numpy.linalg as la 

sizeX=4 
sizeY=2 
sizeZ=5 
a = numpy.random.rand(sizeX,sizeY,sizeZ).astype(numpy.float32) 

ctx = cl.Context() 
queue = cl.CommandQueue(ctx) 

mf = cl.mem_flags 
a_buf = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=a) 
dest_buf = cl.Buffer(ctx, mf.WRITE_ONLY, a.nbytes) 

prg = cl.Program(ctx, """ 
    __kernel void sum(__global const float *a, __global float *b) 
    { 
     int x = get_global_id(0); 
     int y = get_global_id(1); 
     int z = get_global_id(2); 

     int idx = z * %d * %d + y * %d + x; 

     b[idx] = a[idx] * x + 3 * y + 5 * z; 
    } 
    """ % (sizeY, sizeX, sizeX)).build() 

prg.sum(queue, a.shape, a_buf, dest_buf) 
cl.enqueue_read_buffer(queue, dest_buf, a).wait() 
print a 
संबंधित मुद्दे