পাইথনে একটি লুপের সমান্তরালকরণ


35

পাইথনে এমন কোনও সরঞ্জাম রয়েছে যা মতলবের পারফোরের মতো? আমি এই থ্রেডটি পেয়েছি তবে এটি চার বছরের পুরনো। আমি ভেবেছিলাম সম্ভবত এখানে কারওর কাছে আরও সাম্প্রতিক অভিজ্ঞতা থাকতে পারে।

আমি যে ধরণের জিনিসটির সমান্তরাল করতে চাই তার উদাহরণ এখানে:

X = np.random.normal(size=(10, 3))
F = np.zeros((10, ))
for i in range(10):
    F[i] = my_function(X[i,:])

যেখানে my_functionএকটি সময় লাগে ndarrayআকারের (1,3)এবং একটি স্কেলার ফেরৎ।

কমপক্ষে, আমি একসাথে একাধিক কোর ব্যবহার করতে চাই --- পারফোর মতো। অন্য কথায়, 8 থেকে 16 কোরের সাথে একটি ভাগ করা মেমরি সিস্টেমটি ধরুন।


গুগলে প্রচুর ফলাফল। এই বেশ সহজ মনে হচ্ছে: blog.dominodatalab.com/simple-parallelization quora.com/What-is-the-Python-equivalent-of-MATLABs-parfor
ডগ Lipinski

ধন্যবাদ, @ ডগ-লিপিনস্কি। এই উদাহরণগুলি, গুগল করার সময় অন্যদের মতো আমিও পেয়েছি, পুনরাবৃত্তির সূচকগুলির উপর ভিত্তি করে কিছু তুচ্ছ গণনা রয়েছে। এবং তারা সর্বদা দাবি করে যে কোডটি "অবিশ্বাস্যভাবে সহজ"। আমার উদাহরণটি ফর-লুপের বাইরে অ্যারেগুলি (মেমরি বরাদ্দ করে) সংজ্ঞায়িত করে। আমি ঠিক অন্যভাবে এটি করছি; মতলব এটাই আমি এটি করি। যে উদাহরণগুলি মুগ্ধ করে মনে হচ্ছে এমন জটিল অংশটি লুপের ভিতরে ফাংশনে প্রদত্ত অ্যারের অংশ পাচ্ছে।
পল জি কনস্টানটাইন

উত্তর:


19

যাবলিব যা চায় তাই করে। প্রাথমিক ব্যবহারের ধরণটি হ'ল:

from joblib import Parallel, delayed

def myfun(arg):
     do_stuff
     return result

results = Parallel(n_jobs=-1, verbose=verbosity_level, backend="threading")(
             map(delayed(myfun), arg_instances))

যেখানে arg_instancesমানগুলির myfunসমান্তরালে গণনা করা হয় তার তালিকা । মূল সীমাবদ্ধতা হ'ল এটি myfunঅবশ্যই শীর্ষ স্তরের ফাংশন হতে পারে। backendপরামিতি পারেন হতে পারে "threading"বা "multiprocessing"

আপনি সমান্তরাল ফাংশনে অতিরিক্ত সাধারণ পরামিতিগুলি পাস করতে পারেন। এর বডি myfunপ্রাথমিকভাবে গ্লোবাল ভেরিয়েবলগুলি উল্লেখ করতে পারে, মানগুলি যা শিশুদের জন্য উপলব্ধ।

আর্টস এবং ফলাফলগুলি থ্রেডিং ব্যাকএন্ডের সাথে বেশ কিছু হতে পারে তবে ফলাফলগুলি মাল্টিপ্রসেসিং ব্যাকএন্ডের সাথে সিরিয়ালযোগ্য হওয়া দরকার।


ডাস্ক একই ধরণের কার্যকারিতাও সরবরাহ করে। আপনি যদি মূল ডেটা বাইরে নিয়ে কাজ করছেন বা আপনি আরও জটিল কম্পিউটারের সমান্তরালকরণের চেষ্টা করছেন তবে এটি পছন্দনীয়।


আমি মাল্টিপ্রসেসিং সহ ব্যাটারি ব্যবহার করতে শূন্য মান যুক্ত দেখতে পাচ্ছি। আমি বাজলাম যে জবলিব এটি হুডের নীচে ব্যবহার করছে।
জাভিয়ের কম্বেল

1
এটি উল্লেখ করতে হবে যে জবলিব যাদু নয়, threadingব্যাকএন্ড জিআইএল বাধা থেকে ভোগ করে এবং multiprocessingসমস্ত পরামিতি এবং প্রত্যাবর্তনের মানগুলির ক্রমিককরণের কারণে ব্যাকএন্ড বড় ওভারহেড নিয়ে আসে। পাইথনে সমান্তরাল প্রক্রিয়াকরণের নিম্ন-স্তরের বিশদের জন্য এই উত্তরটি দেখুন ।
জাকুব ক্লিঙ্কভস্কý

ফাংশন জটিলতা এবং পুনরাবৃত্তির সংখ্যার সংমিশ্রণটি আমি খুঁজে পাচ্ছি না যার জন্য জবলিব একটি লুপের চেয়ে দ্রুত হবে। আমার জন্য, এটির গতি যদি n_jobs = 1 হয় এবং অন্য সমস্ত ক্ষেত্রে অনেক ধীর হয়
আলেকসেজেস ফমিনস

@ আলেকসজেসফমিন্স থ্রেড ভিত্তিক সমান্তরালতা জিআইএল প্রকাশ না করে এমন কোডের ক্ষেত্রে সহায়তা করবে না তবে একটি উল্লেখযোগ্য সংখ্যক বিশেষত ডাটা সায়েন্স বা সংখ্যাসূচক গ্রন্থাগারগুলিতে কাজ করবে। অন্যথায় আপনার মুটিপ্রসেসিং দরকার, জবলি উভয় সমর্থন করে supports মাল্টিপ্রসেসিং মডিউলটির এখন সমান্তরাল রয়েছে mapযা আপনি সরাসরি ব্যবহার করতে পারেন। এছাড়াও আপনি যদি এমকেএল সংকলিত নিম্পি ব্যবহার করেন তবে এটি কিছু না করে স্বয়ংক্রিয়ভাবে ভেক্টরাইজড ক্রিয়াকলাপগুলিকে সমান্তরাল করে তুলবে। আনানকোনডায় নিমপিটি ডিফল্টরূপে এমকেএল সক্ষম। যদিও এর সর্বজনীন সমাধান নেই। জোবলিব খুব কম গোলমাল করছে এবং 2015 সালে এর পরিমাণ কম ছিল
ড্যানিয়েল

আপনার উপদেশের জন্য ধন্যবাদ. আমার মনে আছে মাল্টিপ্রসেসিংয়ের চেষ্টা করার আগে এবং কয়েকটি পোস্ট লিখেছি, কারণ এটি আমার প্রত্যাশা অনুযায়ী স্কেল হয়নি। হতে পারে আমার এটি অন্য চেহারা দেওয়া উচিত
আলেকসেজ ফমিনস

9

আপনি যা খুঁজছেন তা হ'ল নুম্বা , যা লুপের জন্য অটোকে সমান্তরাল করতে পারে। তাদের ডকুমেন্টেশন থেকে

from numba import jit, prange

@jit
def parallel_sum(A):
    sum = 0.0
    for i in prange(A.shape[0]):
        sum += A[i]

    return sum

8

my_functionনির্বাচনের multiprocessing.Pool().map()ক্ষেত্রে বিশেষ কিছু গ্রহণ না করে এ জাতীয় সহজ লুপগুলিকে সমান্তরাল করার জন্য ভাল অনুমান। joblib, dask, mpiকম্পিউটেশন বা numbaঅন্যান্য উত্তর প্রস্তাবিত মতো ব্যবহারের ক্ষেত্রে কোন সুবিধা আনয়ন এবং যুক্ত করবেন দেখায় বেহুদা নির্ভরতা (যোগফল তারা Overkill হয়)। অন্য উত্তরে প্রস্তাবিত হিসাবে থ্রেডিং ব্যবহার করা ভাল সমাধানের সম্ভাবনা কম, কারণ আপনাকে আপনার কোডের জিআইএল ইন্টারেক্টিভের সাথে ঘনিষ্ঠ হতে হবে বা আপনার কোডটি মূলত ইনপুট / আউটপুট করা উচিত।

এটি বলেছিল numbaক্রমহীন খাঁটি অজগর কোডটি দ্রুততর করা ভাল ধারণা হতে পারে তবে আমি মনে করি এটি প্রশ্নের ক্ষেত্রের বাইরে।

import multiprocessing
import numpy as np

if __name__ == "__main__":
   #the previous line is necessary under windows to not execute 
   # main module on each child under windows

   X = np.random.normal(size=(10, 3))
   F = np.zeros((10, ))

   pool = multiprocessing.Pool(processes=16)
   # if number of processes is not specified, it uses the number of core
   F[:] = pool.map(my_function, (X[i,:] for i in range(10)) )

কিছু সতর্কতা আছে তবে (তবে এটি বেশিরভাগ অ্যাপ্লিকেশনকে প্রভাবিত করে না):

  • উইন্ডোগুলির নীচে কাঁটাচামচ সমর্থন নেই, সুতরাং প্রতিটি সন্তানের প্রারম্ভকালে মূল মডিউল সহ একটি দোভাষী চালু করা হয়, যাতে এটির ওভারহেড থাকতে পারে (বিজ্ঞাপনটি এটির কারণ if __name__ == "__main__"
  • My_function এর আর্গুমেন্টগুলি এবং ফলাফলগুলি পিকেল এবং আন-পিকেলযুক্ত, এটি খুব বেশি ওভারহেড হতে পারে, এটি হ্রাস করার জন্য এই উত্তরটি দেখুন https://stackoverflow.com/a/37072511/128629 । এটি অ চয়নযোগ্য অবজেক্টগুলিকে ব্যবহারযোগ্য করে তোলে না
  • my_functionগ্লোবাল ভেরিয়েবলের সাথে যোগাযোগের মতো ভাগ করা রাষ্ট্রগুলির উপর নির্ভর করা উচিত নয় কারণ প্রক্রিয়াগুলির মধ্যে রাজ্যগুলি ভাগ করা হয় না। খাঁটি ফাংশন (গাণিতিক ইন্দ্রিয়গুলিতে ফাংশন) ফাংশনগুলির উদাহরণ যা ভাগ করে না রাষ্ট্র

6

পারফোর সম্পর্কে আমার ধারণাটি হ'ল ম্যাটল্যাব বাস্তবায়ন বিশদটি এনপ্যাপুলেট করছে, সুতরাং এটি ভাগ করে নেওয়া মেমরি প্যারালালিজম (যা আপনি চান) এবং বিতরণ মেমরি প্যারালালিজম উভয়ই ব্যবহার করতে পারেন (যদি আপনি কোনও চলমান থাকেন তবে) ম্যাটল্যাব কম্পিউটিং সার্ভার বিতরণ )।

আপনি যদি ভাগ করা মেমরি সমান্তরালতা চান এবং আপনি কোনও ধরণের টাস্কের সমান্তরাল লুপটি চালাচ্ছেন , মাল্টিপ্রসেসিং স্ট্যান্ডার্ড লাইব্রেরি প্যাকেজ ডুগের পোস্টে উল্লিখিত যেমন একটি ভাল ফ্রন্ট-এন্ড, যেমন জবলিবের মতো সম্ভবত আপনি চান তা । স্ট্যান্ডার্ড গ্রন্থাগারটি চলে যাচ্ছে না, এবং এটি বজায় রয়েছে, সুতরাং এটি কম ঝুঁকিপূর্ণ।

সমান্তরাল পাইথনের মতো অন্যান্য বিকল্পগুলিও এখানে রয়েছে এবং আইপিসনের সমান্তরাল ক্ষমতাগুলির রয়েছে । সমান্তরাল পাইথনের একটি দ্রুত দৃষ্টিভঙ্গি আমাকে মনে করে যে এটি পারফোরের স্পিরিটের কাছাকাছি, যাতে গ্রন্থাগার বিতরণকৃত মামলার বিবরণ সজ্জিত করে, তবে এটির ব্যয় হ'ল আপনাকে তাদের বাস্তুতন্ত্র গ্রহণ করতে হবে। আইপিথন ব্যবহারের ব্যয় একই রকম; আপনাকে কাজ করার আইপিথন পদ্ধতি অবলম্বন করতে হবে, এটি আপনার পক্ষে উপযুক্ত বা নাও হতে পারে।

যদি আপনি বিতরণ মেমরি সম্পর্কে যত্নশীল হন তবে আমি mpi4py সুপারিশ করি । লিসানড্রো ডালসিন দুর্দান্ত কাজ করে এবং পিইটিএসসি পাইথন র‍্যাপারগুলিতে এমপিআই 4পি ব্যবহার করা হয়, তাই আমি মনে করি না এটি শীঘ্রই খুব শীঘ্রই চলে যাচ্ছে। মাল্টিপ্রসেসিংয়ের মতো এটি পারফোরের তুলনায় সমান্তরালতার জন্য কম (এরি) ওপেন ইন্টারফেস, তবে এটি কিছু সময়ের জন্য স্থায়ী হয়।


ধন্যবাদ, জিফ এই লাইব্রেরিগুলির সাথে কাজ করার কোনও অভিজ্ঞতা আছে কি? সম্ভবত আমি একটি ভাগ করা মেমরি মেশিন / মাল্টিকোর প্রসেসরের এমপিআই 4পি ব্যবহার করার চেষ্টা করব।
পল জি। কনস্টানটাইন

@ পলজিগনস্ট্যান্টাইন আমি এমপিআইপিপি সফলভাবে ব্যবহার করেছি; এটি বেশ বেদাহীন, যদি আপনি এমপিআইয়ের সাথে পরিচিত হন। আমি মাল্টিপ্রসেসিং ব্যবহার করি নি, তবে আমি এটি সহকর্মীদের কাছে সুপারিশ করেছি, যারা বলেছিলেন এটি তাদের পক্ষে ভাল কাজ করেছে। আমি আইপিথনও ব্যবহার করেছি, তবে প্যারালালিজম বৈশিষ্ট্যগুলি নয়, সুতরাং এটি কতটা ভাল কাজ করে আমি তার সাথে কথা বলতে পারি না।
জিফ অক্সবেরি

1
: Aron একটা চমৎকার mpi4py টিউটোরিয়াল তিনি অবশ্যই সুপারকম্পিউটিং এ PyHPC জন্য প্রস্তুত করা হয়েছে github.com/pyHPC/pyhpc-tutorial
ম্যাট Knepley

4

"ব্ল্যাক বক্স" সরঞ্জামটি সন্ধান করার আগে, এটি সমান্তরাল "জেনেরিক" পাইথন ফাংশনে কার্যকর করতে ব্যবহার করা যেতে পারে, আমি কীভাবে my_function()হাত দিয়ে সমান্তরাল হতে পারি তা বিশ্লেষণ করার পরামর্শ দেব ।

প্রথমে my_function(v)পাইথন forলুপের ওভারহেডের সাথে মৃত্যুদন্ড কার্যকর করার সময়টির তুলনা করুন : [সি] পাইথন forলুপগুলি বেশ ধীর, সুতরাং এতে ব্যয় করা সময় my_function()নগণ্য হতে পারে।

>>> timeit.timeit('pass', number=1000000)
0.01692986488342285
>>> timeit.timeit('for i in range(10): pass', number=1000000)
0.47521495819091797
>>> timeit.timeit('for i in xrange(10): pass', number=1000000)
0.42337894439697266

দ্বিতীয় চেকের জন্য যদি সেখানে কোনও সাধারণ ভেক্টর বাস্তবায়ন হয় my_function(v)যার জন্য লুপগুলির প্রয়োজন হয় না:F[:] = my_vector_function(X)

(এই দুটি প্রথম বিষয়টি বেশ তুচ্ছ, আমি যদি এখানে কেবল সম্পূর্ণতার জন্য উল্লেখ করেছি তবে আমাকে ক্ষমা করুন))

তৃতীয় এবং সবচেয়ে গুরুত্বপূর্ণ পয়েন্ট, CPython বাস্তবায়নের জন্য অন্তত কিনা চেক করা হল my_functionএটা অধিকাংশ সময় ব্যয় ভিতরে বা বাহিরে বিশ্বব্যাপী অনুবাদক লক , বা Gil । যদি জিআইএল এর বাইরে সময় ব্যয় করা হয় তবে threadingস্ট্যান্ডার্ড লাইব্রেরি মডিউলটি ব্যবহার করা উচিত। ( এখানে একটি উদাহরণ)। বিটিডাব্লু, my_function()কেবলমাত্র জিআইএল প্রকাশের জন্য সি-এক্সটেনশন হিসাবে লেখার কথা ভাবতে পারে ।

অবশেষে, my_function()জিআইএল মুক্তি না দিলে , কেউ multiprocessingমডিউলটি ব্যবহার করতে পারে ।

তথ্যসূত্র: সমান্তরাল কার্যনির্বাহীকরণে পাইথন ডক্স এবং সমান্তরাল প্রক্রিয়াকরণে নিমপি / স্কিপি ইন্ট্রো


2

আপনি জুলিয়া চেষ্টা করতে পারেন। এটি পাইথনের খুব কাছাকাছি এবং এতে প্রচুর ম্যাটল্যাব নির্মাণ রয়েছে। এখানে অনুবাদটি হ'ল:

F = @parallel (vcat) for i in 1:10
    my_function(randn(3))
end

এটি এলোমেলো সংখ্যাকেও সমান্তরাল করে তোলে, এবং হ্রাসের সময় শেষ পর্যন্ত ফলাফলগুলিকে সম্মতি দেয়। এটি মাল্টিপ্রসেসিং ব্যবহার করে (সুতরাং আপনাকে addprocs(N)ব্যবহারের আগে প্রক্রিয়াগুলি যুক্ত করতে হবে এবং এই ব্লগ পোস্টে দেখানো হিসাবে এটি এইচপিসিতে একাধিক নোডেও কাজ করে )।

pmapপরিবর্তে আপনি এটি ব্যবহার করতে পারেন :

F = pmap((i)->my_function(randn(3)),1:10)

আপনি যদি থ্রেডের সমান্তরালতা চান তবে আপনি ব্যবহার করতে পারেন Threads.@threads(তবে নিশ্চিত করুন আপনি আলগোরিদম থ্রেড-নিরাপদ করেছেন)। জুলিয়া খোলার আগে, পরিবেশ পরিবর্তনশীল JULIA_NUM_THREADS সেট করুন, তারপরে এটি হ'ল:

Ftmp = [Float64[] for i in Threads.nthreads()]
Threads.@threads for i in 1:10
    push!(Ftmp[Threads.threadid()],my_function(randn(3)))
end
F = vcat(Ftmp...)

এখানে আমি প্রতিটি থ্রেডের জন্য পৃথক অ্যারে তৈরি করি, যাতে অ্যারে যুক্ত করার সময় তারা সংঘর্ষে না যায়, তারপরে কেবল অ্যারেগুলি সংযুক্ত করুন। থ্রেডিং বেশ নতুন তাই ঠিক এখন থ্রেডগুলির সরাসরি ব্যবহার রয়েছে, তবে আমি নিশ্চিত যে থ্রেডেড হ্রাস এবং মানচিত্রগুলি মাল্টিপ্রসেসিংয়ের মতোই যুক্ত হবে।


0

আমি জবলিব লাইব্রেরির সমান্তরাল এবং বিলম্বিত ফাংশনগুলি ব্যবহার করার জন্য "টেম্পাইল" মডিউলটি ব্যবহার করার পরামর্শ দিচ্ছি বিশাল অ্যারেগুলির জন্য টেম্প শেয়ার করা মেমরি তৈরি করতে, উদাহরণ এবং ব্যবহারটি এখানে পাওয়া যাবে https://pythonhosted.org/joblib/parallel.html

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.