2012-06-01 10 views
10

क्या ओपनसीएल को उन सभी अद्वितीय भौतिक उपकरणों की सूची देने का कोई तरीका है जिनके पास ओपनसीएल कार्यान्वयन उपलब्ध है? मुझे पता है कि मंच/डिवाइस सूची के माध्यम से पुन: प्रयास कैसे करें, उदाहरण के लिए, मेरे मामले में, मेरे पास एक इंटेल-प्रदान किया गया प्लेटफॉर्म है जो मुझे मेरे सीपीयू के लिए एक कुशल डिवाइस कार्यान्वयन देता है, और एपीपी मंच जो मेरे जीपीयू के लिए तेजी से कार्यान्वयन प्रदान करता है लेकिन मेरे सीपीयू के लिए एक भयानक कार्यान्वयन।ओपनसीएल डिवाइस विशिष्टता

क्या यह काम करने का कोई तरीका है कि दो सीपीयू डिवाइस वास्तव में एक ही भौतिक उपकरण हैं, ताकि मैं सबसे कुशलता का चयन कर सकूं और इसके साथ काम कर सकूं, दोनों का उपयोग करने और उन्हें एक दूसरे के साथ संघर्ष करने के बजाय एक भौतिक उपकरण पर गणना समय?

मैं CL_DEVICE_VENDOR_ID और CL_DEVICE_NAME पर ध्यान दिया है, लेकिन वे मेरी मुद्दों को हल नहीं है, CL_DEVICE_NAME एक ही मॉडल की दो अलग-अलग भौतिक उपकरणों के लिए ही होगा (दोहरी GPU है) और CL_DEVICE_VENDOR_ID मुझे आधार पर मेरी सीपीयू के लिए एक अलग आईडी देता है प्लैटफ़ार्म पर।

एक आदर्श समाधान कुछ प्रकार की अद्वितीय भौतिक डिवाइस आईडी होगी, लेकिन मैं स्वयं डिवाइस को पुनर्व्यवस्थित करने के लिए ओपनसीएल कॉन्फ़िगरेशन को मैन्युअल रूप से बदलने से खुश हूं (यदि ऐसी कोई चीज़ संभव है)।

+0

मुझे प्रश्न नहीं मिला .. तो आप समान चश्मे के साथ दो सीपीयू के बीच चयन करना चाहते हैं? – ardiyu07

+0

मैं सभी उपलब्ध भौतिक उपकरणों (आसानी से समांतर समस्या के लिए) का उपयोग करना चाहता हूं - और मैं भौतिक उपकरण द्वारा केवल एक लॉजिकल डिवाइस का उपयोग करना चाहता हूं अन्यथा मुझे विवाद मिलता है। – Thomas

उत्तर

2

जहां तक ​​मैं अब इस मुद्दे की जांच कर सकता हूं, कोई विश्वसनीय समाधान नहीं है। यदि आपका पूरा काम एक ही प्रक्रिया में किया जाता है, तो आप clGetDeviceIDs या cl_device द्वारा लौटाई गई प्रविष्टियों के क्रम का उपयोग कर सकते हैं (अनिवार्य रूप से वे पॉइंटर्स हैं), लेकिन यदि आप उन पहचानकर्ताओं को प्रक्रियाओं के बीच साझा करने का प्रयास करते हैं तो चीजें बदतर हो जाती हैं।

मुद्दा यह है कि अगर आप दो समान GPUs है, तो आप उन दोनों के बीच भेद नहीं कर सकते है:

कह that guy's blog post इसके बारे में देखें। यदि आप clGetDeviceIDs पर कॉल करते हैं, तो जिस क्रम में उन्हें वापस किया जाता है वह वास्तव में अनिर्दिष्ट है, इसलिए यदि पहली प्रक्रिया पहले डिवाइस को चुनती है और दूसरा दूसरा डिवाइस लेता है, तो वे दोनों एक ही जीपीयू को ओवरसब्सक्राइब करने और दूसरे को निष्क्रिय करने के लिए हवादार हो सकते हैं।

हालांकि, उनका यह भी कहना है कि NVIDIA और AMD अपने कस्टम एक्सटेंशन, cl_amd_device_topology और cl_nv_device_attribute_query प्रदान करते हैं। चाहे ये एक्सटेंशन आपके डिवाइस के द्वारा समर्थित हैं आप जाँच कर सकते हैं, और फिर उन्हें निम्नलिखित (मूल लेखक द्वारा कोड) के रूप में उपयोग:

// This cl_ext is provided as part of the AMD APP SDK 
#include <CL/cl_ext.h> 

cl_device_topology_amd topology; 
status = clGetDeviceInfo (devices[i], CL_DEVICE_TOPOLOGY_AMD, 
    sizeof(cl_device_topology_amd), &topology, NULL); 

if(status != CL_SUCCESS) { 
    // Handle error 
} 

if (topology.raw.type == CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD) { 
    std::cout << "INFO: Topology: " << "PCI[ B#" << (int)topology.pcie.bus 
     << ", D#" << (int)topology.pcie.device << ", F#" 
     << (int)topology.pcie.function << " ]" << std::endl; 
} 

या (मेरे द्वारा कोड, ऊपर लिंक पोस्ट से रूपांतरित):

#define CL_DEVICE_PCI_BUS_ID_NV 0x4008 
#define CL_DEVICE_PCI_SLOT_ID_NV 0x4009 

cl_int bus_id; 
cl_int slot_id; 

status = clGetDeviceInfo (devices[i], CL_DEVICE_PCI_BUS_ID_NV, 
    sizeof(cl_int), &bus_id, NULL); 
if (status != CL_SUCCESS) { 
    // Handle error. 
} 

status = clGetDeviceInfo (devices[i], CL_DEVICE_PCI_BUS_ID_NV, 
    sizeof(cl_int), &slot_id, NULL); 
if (status != CL_SUCCESS) { 
    // Handle error. 
} 

std::cout << "Topology = [" << bus_id << 
         ":"<< slot_id << "]" << std::endl; 
+0

"जिस क्रम में उन्हें वापस किया गया है वह वास्तव में अनिर्दिष्ट है" वाह! यह मेरी अपेक्षा से भी बदतर है। वैसे भी मेरा प्रश्न एकाधिक प्रक्रियाओं के बारे में इतना नहीं था, लेकिन एक ही भौतिक उपकरण (जैसे इंटेल एसडीके और एएमडी एसडीके दोनों को एक ही मुख्य सीपीयू को उनके प्रत्येक संबंधित प्लेटफ़ॉर्म में लॉजिकल डिवाइस के रूप में उजागर करने के लिए अलग-अलग प्लेटफार्मों के बारे में अधिक जानकारी) लेकिन यह टोपोलॉजी एक्सटेंशन यह भी हल करता है। जवाब के लिए धन्यवाद! – Thomas

+0

@ थॉमस: आपका स्वागत है! बीटीडब्ल्यू, 'क्लिनफो' कार्यक्रम को एनवीडिया और एएमडी उपकरणों दोनों के लिए टोपोलॉजी आइडेंटिफायर प्रदर्शित करना चाहिए। आपको निश्चित रूप से [देखना चाहिए] (https://github.com/Oblomov/clinfo/blob/f9516865c0a47d2e2b24eb8371f0931792a23316/src/clinfo.c#L1048) वे इससे कैसे निपटते हैं, उनका कोड मेरे से बेहतर प्रतीत होता है। – firegurafiku

0

वैसे भी सिर्फ मानते हैं कि आप सभी उपकरणों के लिए विशिष्ट आईडी खींचने की कोशिश कर रहे हैं, वास्तव में आप बस clGetDeviceIDs साथ क्वेरी कर सकते हैं:

cl_int clGetDeviceIDs(cl_platform_id platform, 
         cl_device_type device_type, 
         cl_uint num_entries, 
         cl_device_id *devices, 
         cl_uint *num_devices) 

फिर डिवाइस की अपनी सूची * उपकरणों सरणी डाला जाएगा , और उसके बाद आप यह पता लगाने के लिए कि आप किस डिवाइस का उपयोग करना चाहते हैं, clgetDeviceInfo() कर सकते हैं।

+0

मैं उन सभी का उपयोग करना चाहता हूं लेकिन मैं नहीं चाहता कि किसी भी भौतिक डिवाइस को कई लॉजिकल उपकरणों द्वारा एक्सेस किया जाए। – Thomas

+0

अगर मुझे यह गलत नहीं मिल रहा है तो आप एक ही समय में चल रहे सभी उपकरणों के साथ मल्टीथ्रेड करना चाहते हैं? यदि ऐसा है तो आप OpenCL, oclMultiTreads स्रोत कोड के लिए CUDA के कंप्यूटिंग एसडीके पर एक नज़र डालना चाहते हैं, जहां आप मैन्युअल रूप से कार्य को विभाजित कर सकते हैं और फिर उन्हें उपलब्ध डिवाइस – ardiyu07

+0

के साथ असीमित रूप से चला सकते हैं, मेरा प्रश्न उससे अधिक सूक्ष्म है। मुझे पता है कि मैं सभी उपकरणों को सूचीबद्ध कर सकता हूं और उन्हें मल्टीथ्रेड कर सकता हूं। लेकिन मुद्दा यह है कि एक एकल भौतिक उपकरण (कहता है, मेरा अनूठा सीपीयू) दो लॉजिकल डिवाइस (प्रत्येक ओपनसीएल प्लेटफ़ॉर्म में से एक) के रूप में आता है - दो लॉजिकल डिवाइसों पर मल्टीथ्रेडिंग अद्वितीय भौतिक CPU पर संसाधन विवाद का कारण बनता है (यह और भी अधिक है GPU के लिए सच है) इसलिए मैं यह जानना चाहता हूं कि दो लॉजिकल डिवाइस एक ही भौतिक डिवाइस पर इंगित करते हैं और केवल उनमें से एक का उपयोग करते हैं। – Thomas

2
  • आप एक मंच से संबंधित ठीक उसी तरह का दो उपकरणों है, तो आप उन्हें अलग clGetDeviceIDs से जुड़े cl_device_ids वापसी से बता सकते हैं।

  • यदि आपके पास ऐसे डिवाइस हैं जिनका उपयोग दो अलग-अलग प्लेटफार्मों द्वारा किया जा सकता है, तो आप CL_DEVICE_NAME से डिवाइस नामों की तुलना करके दूसरे प्लेटफॉर्म के लिए प्रविष्टियों को खत्म कर सकते हैं।

  • यदि आप किसी डिवाइस के लिए इच्छित प्लेटफ़ॉर्म ढूंढना चाहते हैं, तो CLGetPlatformInfo() और clGetDeviceInfo से क्रमशः CL_PLATFORM_VENDOR और CL_DEVICE_VENDOR स्ट्रिंग की तुलना करें।

आप सभी प्लेटफार्मों और अलग प्लेटफ़ॉर्म-विशिष्ट सूचियों में अपने सभी संबद्ध उपकरणों में पढ़ सकते हैं और उसके बाद अलग-अलग सूचियों में डिवाइस नाम की तुलना द्वारा युगल को समाप्त। यह सुनिश्चित करना चाहिए कि आपको अलग-अलग प्लेटफ़ॉर्म के लिए एक ही डिवाइस न मिलें।

अंत में आप कमांड लाइन तर्क या कॉन्फ़िगरेशन फ़ाइल द्वारा उदाहरण के लिए, एक विशिष्ट प्लेटफार्म के साथ एक निश्चित प्रकार (सीपीयू, जीपीयू, त्वरक) के उपकरणों को जोड़ने के लिए अपने आवेदन के लिए तर्क दे सकते हैं यदि विभिन्न प्लेटफ़ॉर्म के विकल्प मौजूद हैं एक उपकरण प्रकार। उम्मीद है कि यह आपके प्रश्न का उत्तर देगा।

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