2011-09-01 14 views
13

Tôi muốn có thể kết hợp các thiết bị OpenCL với GPU trong hệ thống trên các hệ thống đa GPU được xác định bằng ID PCI.Làm thế nào để kết hợp các thiết bị OpenCL với một GPU cụ thể cho các nhà cung cấp PCI, ID thiết bị và bus trong một hệ thống đa GPU?

Ví dụ: nếu tôi có một hệ thống có nhiều GPU, có thể từ các nhà cung cấp khác nhau, tôi có thể liệt kê các thiết bị bằng cách liệt kê bus PCI. Điều này mang lại cho tôi nhà cung cấp PCI, thiết bị và ID xe buýt. Nếu tôi chọn một trong các thiết bị PCI (GPU) này để sử dụng cho tính toán OpenCL dựa trên một số tiêu chí lựa chọn, làm cách nào để kết hợp nó với thiết bị OpenCL?

Tôi có thể liệt kê các thiết bị GPU trong OpenCL sử dụng clGetDeviceIDs() nhưng không có cách nào rõ ràng để khớp thiết bị OpenCL với thiết bị PCI. Chức năng OpenCL clGetDeviceInfo() cung cấp quyền truy cập vào ID nhà cung cấp PCI và tên thiết bị nhưng không cung cấp ID thiết bị hoặc ID bus. Tôi có thể cố gắng để phù hợp với tên thiết bị PCI với tên thiết bị OpenCL nhưng nó có thể là bạn có nhiều hơn một trong cùng một loại thiết bị và các tên không phải luôn luôn giống nhau anyway.

Tại sao điều này lại cần thiết? Nói rằng tôi biết rằng chương trình X đang chạy CUDA hoặc cái gì khác trên GPU A. Tôi muốn tránh sử dụng GPU A cho một hoạt động OpenCL vì vậy tôi chọn GPU B. Sau đó tôi cần tìm ra thiết bị OpenCL nào là GPU A và GPU là gì B. Các ID PCI có vẻ là cách duy nhất và nền tảng chéo để xác định các thiết bị GPU.

BTW, API CUDA cung cấp cho bạn ID PCI, bus và slot (CU_DEVICE_ATTRIBUTE_PCI_BUS_ID, CU_DEVICE_ATTRIBUTE_PCI_DEVICE_ID) nhưng CUDA chỉ hoạt động với các thiết bị NVidia.

Lý tưởng nhất là tôi cần giải pháp bằng cách sử dụng C hoặc C++.

+0

Thông số nói CL_DEVICE_VENDOR_ID "có thể là ID PCIe". Nếu điều đó không có được những gì bạn muốn, thì tôi không nghĩ rằng có bất cứ điều gì trong spec đó sẽ. Tuy nhiên, không chắc chắn tại sao bạn cần điều này. Âm thanh như tối ưu hóa sớm. – vocaro

+0

@vocaro: Có, tôi có thể lấy ID nhà cung cấp. Tôi không nghĩ bạn hiểu câu hỏi. – jcoffland

+0

Bạn nói rằng bạn muốn biết ID thiết bị PCI để tránh tranh chấp với một quá trình khác có thể đang sử dụng một ID thiết bị PCI cụ thể. Tôi tự hỏi làm thế nào bạn biết thiết bị PCI nào đang được sử dụng? Tôi đoán bạn không sử dụng OpenCL cho điều đó? – Matt

Trả lời

5

Cách để thực hiện việc này là sử dụng hai tiện ích mở rộng dành riêng cho nhà cung cấp. Đối với AMD, bạn phải sử dụng CL_DEVICE_TOPOLOGY_AMD hoạt động trên Windows và Linux và sẽ trả lại id bus PCIe, là duy nhất cho GPU. Trên NVIDIA, truy vấn thiết bị cho CL_DEVICE_PCI_BUS_ID_NV. Xem thêm: https://anteru.net/2014/08/01/2483/

+0

Tôi chưa thử điều này nhưng có vẻ như đó là câu trả lời đúng. Tuyệt vời, cảm ơn câu trả lời và sau gần 3 năm chờ đợi. – jcoffland

+0

Xin lỗi đã quá lâu, tôi không gặp vấn đề trước đó :) Và cảm ơn bạn đã đánh dấu câu trả lời này là câu trả lời chính xác. – Anteru

+0

'CL_DEVICE_PCI_BUS_ID_NV' có hoạt động với trình điều khiển Nvidia trên Windows không? Tôi đang cố gắng này trong PyOpenCL nhưng tiếp tục nhận được một lỗi rằng nó là một giá trị không hợp lệ. – chippies

0

Phiên bản mới nhất của AMD có phần mở rộng cl_device_topology_amd trên Linux, thêm tùy chọn CL_DEVICE_TOPOLOGY_AMD vào clGetDeviceInfo(), nhưng đó là một giải pháp khá hẹp.

+0

Vâng, cần phải bao gồm thẻ của NVIDIA. – jcoffland

-1

Tôi đã phát triển một thư viện để làm điều đó: giữ mô phỏng OpenCL từ bước trên từng ngón chân khác.

Bạn sẽ tìm thấy nó ở đây: https://github.com/nbigaouette/oclutils/

Nó đầu tiên liệt kê tất cả các nền tảng và mọi thiết bị cho mỗi nền tảng hiện tại trên máy tính này. Bạn chọn nền tảng mong muốn và nó sẽ chọn thiết bị tốt nhất có sẵn. Tôi sử dụng nó trên máy trạm của tôi với 3 thẻ nvidia: hai GTX 580 cho tính toán OpenCL và một GT 210 cho màn hình. Chạy hai mô phỏng cùng một lúc sẽ chạy trên hai GTX riêng biệt. không can thiệp.

Ngoài ra còn có một lớp học tốt đẹp mà sẽ giữ hai bộ đệm đồng bộ: một trên máy chủ và một trên thiết bị. Gọi OpenCL_Array :: Host_to_Device() và OpenCL_Array :: Device_to_Host() làm cho việc chuyển đổi qua lại đơn giản.

Nó hoạt động với các nền tảng:

  • nvidia (chỉ GPU)
  • AMD (CPU và/hoặc GPU)
  • intel (CPU chỉ)
  • táo (CPU và/hoặc GPU)

Lưu ý rằng nó sẽ không cho phép bạn chọn nên sử dụng thiết bị nào nhưng chọn một thiết bị cho bạn.Nếu hai trường hợp của một chương trình sử dụng thư viện, họ sẽ biết nó và sẽ không chạy trên cùng một thiết bị (nếu bạn có quá, tất nhiên). Nó cũng không thể, ngay bây giờ, để phát hiện nếu thẻ video được sử dụng cho màn hình. Nhưng ít nhất đó là một sự khởi đầu!

+0

Khi tôi hiểu câu trả lời của bạn không giải quyết được vấn đề kết hợp ID thiết bị PCI với các thiết bị tính toán OpenCL. Bạn đang giải quyết một vấn đề liên quan nhưng nó không giúp ích cho những gì tôi cần. Nếu tôi sai, hãy giải thích. Hãy nhớ rằng tôi cũng muốn có thể sử dụng CUDA và vẫn theo dõi thiết bị nào là CUDA. – jcoffland

1

Thật không may câu trả lời bạn đang tìm kiếm không phải là do bản chất trừu tượng của openCL. Cách duy nhất tôi đã tìm thấy để thực hiện một cách đáng tin cậy là gán khối lượng công việc yêu cầu cho nền tảng + ID thiết bị trong openCL, và sau đó theo dõi quá trình sử dụng thông qua các công cụ như ADL của AMD và NVML của Nvidia. Ngay cả các ứng dụng trưởng thành như cgminer có vấn đề với điều này và thường trộn lẫn khối lượng công việc openCL với số liệu thẻ, nhiều đến mức chúng gán các biến cấu hình để sửa nó theo cách thủ công ("bản đồ gpu").

Tôi muốn có một câu trả lời tốt hơn cho bây giờ bởi vì nó sẽ là tuyệt vời để biết, thông qua openCL, thiết bị nào đằng sau điểm cuối! Điều này có thể thay đổi trong tương lai, khi AMD đang làm việc để thêm lớp này để mởCL như arsenm đã chỉ ra.

0

Dường như câu trả lời Anteru là đúng, nhưng chỉ khi bạn đang chạy Linux/mac. Sau một số thử nghiệm tôi đã làm, có vẻ như các cửa sổ không nhận ra các tiện ích mở rộng cụ thể của nhà cung cấp này. (Tôi đã thử nghiệm nó trên cả Geforce GTX Titan & ATI Radeon R9)

Giải pháp của tôi cho bạn là sử dụng clGetGLContextInfoKHR() chức năng (có sẵn từ OpenCL đặc tả 1.1) với tham số "CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR", và điều đó sẽ đảm bảo bạn sẽ có được ID thiết bị openCL có cùng một GPU thực hiện hiển thị.

Đúng, điều đó sẽ không cung cấp cho bạn khe xe buýt vật lý, nhưng điều đó sẽ đảm bảo cùng GPU mà hiển thị là cùng một GPU tính toán!

Ngoài ra, giả sử một thẻ hoạt động với thẻ Nvidia Quadro, bạn có thể sử dụng wgl_nv_gpu_affinity để đảm bảo truy cập OpenGL một GPU cụ thể và sau đó sử dụng ngữ cảnh GL & lấy từ ID thiết bị openCL.

Các vấn đề liên quan