2014-01-07 2 views
1

Я пытаюсь распараллелить код, который я сделал, чтобы генерировать некоторые изображения случайным образом (для конкретной проблемы, над которой я работаю). Как я использую классы, и я обнаружил, что это не просто для многопроцессорных методов, я искал некоторые альтернативы и нашел этот подход:Многопроцессорство с классами/Возвращаемый список - Python

#https://gist.github.com/fiatmoney/1086393 
#MultiprocessingMethods.py 

def _pickle_method(method): 
    func_name = method.im_func.__name__ 
    obj = method.im_self 
    cls = method.im_class 
    if func_name.startswith('__') and not func_name.endswith('__'): #deal with mangled names 
     cls_name = cls.__name__.lstrip('_') 
     func_name = '_' + cls_name + func_name 
    return _unpickle_method, (func_name, obj, cls) 


def _unpickle_method(func_name, obj, cls): 
    for cls in cls.__mro__: 
     try: 
      func = cls.__dict__[func_name] 
     except KeyError: 
      pass 
     else: 
      break 
    return func.__get__(obj, cls) 

Итак, я применил это к моему коду:

from multiprocessing import Pool 
from PIL import Image 

import MultiprocessingMethods as Mp 
import Utils 

import random 
import pylab as plt 
import copy_reg 
import types 

copy_reg.pickle(types.MethodType, Mp._pickle_method, Mp._unpickle_method) 

class ImageData(object): 

    def __init__(self, width, height, range_min=-1, range_max=1): 
     self.width = width 
     self.height = height 
     #The values range each pixel can assume 
     self.range_min = range_min 
     self.range_max = range_max 
     self.data = [] 
     for i in range(width): 
      self.data.append([0] * height) 

    def generate_heat_map_image(self, name): 
     """ 
     Generate a heat map of the image 
     :param name: the name of the file 
     """ 
     #self.normalize_image_data() 
     plt.figure() 
     fig = plt.imshow(self.data, extent=[-1, 1, -1, 1]) 
     plt.colorbar(fig) 
     plt.savefig(name+".png") 
     plt.close() 

    def shepard_interpolation(self, seeds=10): 
     print type (self.data) 
     #Code omitted 'cause it doesn't effect the problem 
     return self.data 


if __name__ == '__main__': 
    x = [ImageData(50, 50), ImageData(50, 50)] 
    p = Pool() 
    outputs = p.map(ImageData.shepard_interpolation,x) 

    #A [[[ ]]] 
    print outputs 
    for i in range(len(outputs)): 
     # A [[ ]] 
     print outputs[i] 
     outputs[i].generate_heat_map_image("ImagesOutput/Entries/Entry"+str(i)) 

Теперь я может распараллелить мой процесс, но я получаю как вывод массива массивов, и я не знаю почему. До этого у меня всегда был массив ImageData, и я мог генерировать изображение тепловой карты с matplotlib. Имеет ли этот вид доход какое-то отношение к многопроцессорности? Думаю, что так, потому что я получаю объект AttributeError: «list» не имеет атрибута «generate_heat_map_image», а return должен быть списком типа ImageData или списком списков. Можно ли вернуть массив ImageData?

Любая помощь будет оценена по достоинству. Спасибо заранее.

ответ

1

Решено. Мне просто пришлось поставить:

def shepard_interpolation(self, seeds=10): 
    print type (self.data) 
    #Code omitted 'cause it doesn't effect the problem 
    return self 

Вещи, которые происходят после 5 безответных часов программирования. Спасибо, ребята.

1

Недостаточно идентификатор класса ImageData, поэтому ваш метод фактически не принадлежит классу, даже без многопроцессорности; здесь является правильным:

class ImageData: 
    def __init__(self, width, height, range_min=-1, range_max=1): 
     self.width = width 
     self.height = height 
     #Which values each pixel can assume 
     self.range_min = range_min 
     self.range_max = range_max 
     self.data = [] 
     for i in range(width): 
      self.data.append([0] * height) 

    def interpolate_points(self, seeds): 
     points = [] 
     f = [] 
     for i in range(seeds): 
      # Generate a cell position 
      pos_x = random.randrange(self.width) 
      pos_y = random.randrange(self.height) 

      # Save the f(x,y) data 
      x = Utils.translate_range(pos_x, 0, self.width, self.range_min, self.range_max) 
      y = Utils.translate_range(pos_y, 0, self.height, self.range_min, self.range_max) 
      z = Utils.function(x, y) 
      points.append([x, y]) 

      f.append(z) 
     for x in range(self.width): 
      xt = (Utils.translate_range(x, 0, self.width, self.range_min, self.range_max)) 
      for y in range(self.height): 
       yt = (Utils.translate_range(y, 0, self.height, self.range_min, self.range_max)) 
       self.data[x][y] = Utils.shepard_euclidian(points, f, [xt, yt], 3) 

    # >>>> Note the identation change here! 
    def generate_heat_map_image(self, name): 
     """ 
     Generate a heat map of the image 
     :param name: the name of the file 
     """ 

     #self.normalize_image_data() 
     plt.figure() 
     fig = plt.imshow(self.data, extent=[-1, 1, -1, 1]) 
     plt.colorbar(fig) 
     plt.savefig(name+".png") 
     plt.close() 
+0

Отступ в моем коде в порядке. Это была проблема, когда я вставил ее. Я отредактирую. – pceccon

+0

Какая ошибка/исключение вы получаете? Можете ли вы опубликовать трассировку стека? –

+0

Я обнаружил, что применять многопроцессорную обработку с Python не просто. Я нашел альтернативу, но у меня все еще есть проблемы. Я уточню свой вопрос. Спасибо, @ F.X. – pceccon

Смежные вопросы