====== Konfiguracja środowiska C/C++ OpenCL na Windows ====== ===== Pliki rozwojowe OpenCL ===== Pliki te możesz pobrać tutaj: [[https://github.com/KhronosGroup/OpenCL-SDK/releases/tag/v2024.10.24]]. Dla Windowsa jest to plik ''OpenCL-SDK-v2024.10.24-Win-x64.zip''. Rozpakuj katalog z zipa w dogodnym dla Ciebie miejscu. W moim przypadku: ''C:\OpenCL-SDK-v2024.10.24-Win-x64''. W środku powinny się znajdować cztery katalogi: bin, include, lib i share. ===== Konfiguracja Visual Studio 2022 ===== Utwórz nowy projekt o typie "C++ Windows Console App". Na górze ekranu, rozwiń opcję "Local Windows Debugger" i kliknij " Debug Properties". {{ :public:wikiblog:22-05-2025-1.png?direct |}} Rozwiń pole "Configuration" i zmień opcję na "All Configurations". {{ :public:wikiblog:22-05-2025-2.png?direct |}} W zakładce "C/C++", dodaj ścieżkę do katalogu "include" w opcji "Additional Include Directories". {{ :public:wikiblog:22-05-2025-3.png?direct |}} W zakładce "Linker", dodaj ścieżkę do katalogu "lib" w opcji "Additional Library Directories". {{ :public:wikiblog:22-05-2025-4.png?direct |}} W zakładce "Linker"->"Input", dodaj następujące wartości w opcji "Additional Dependencies": ''OpenCL.lib;OpenCLExt.lib;OpenCLUtils.lib;OpenCLUtilsCpp.lib;OpenCLUtilsCppd.lib;OpenCLUtilsd.lib;''. {{ :public:wikiblog:22-05-2025-5.png?direct |}} Kliknij przycisk "Apply" i zamknij okno przyciskiem "Ok". ===== Kompilacja ===== Możesz wkleić przykładowy kod i uruchomić go zieloną strzałką na górze okna. (Kod wygenerowany przez GPT-4o, licencja nieznana) #define CL_TARGET_OPENCL_VERSION 120 #include #include #include #include void print_device_info(cl_device_id device) { char buffer[1024]; cl_uint uint_val; cl_ulong ulong_val; size_t size_val[3]; cl_device_fp_config fp_config; cl_bool bool_val; clGetDeviceInfo(device, CL_DEVICE_NAME, sizeof(buffer), buffer, NULL); printf(" Device: %s\n", buffer); cl_device_type type; clGetDeviceInfo(device, CL_DEVICE_TYPE, sizeof(type), &type, NULL); printf(" Type: %s\n", (type & CL_DEVICE_TYPE_GPU) ? "GPU" : "Other"); clGetDeviceInfo(device, CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(uint_val), &uint_val, NULL); printf(" Compute Units: %u\n", uint_val); clGetDeviceInfo(device, CL_DEVICE_MAX_CLOCK_FREQUENCY, sizeof(uint_val), &uint_val, NULL); printf(" Max Clock Frequency: %u MHz\n", uint_val); clGetDeviceInfo(device, CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(ulong_val), &ulong_val, NULL); printf(" Global Memory: %.2f GB\n", ulong_val / (1024.0 * 1024.0 * 1024.0)); clGetDeviceInfo(device, CL_DEVICE_LOCAL_MEM_SIZE, sizeof(ulong_val), &ulong_val, NULL); printf(" Local Memory: %.2f KB\n", ulong_val / 1024.0); clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(size_val[0]), &size_val[0], NULL); printf(" Max Work Group Size: %zu\n", size_val[0]); clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, sizeof(uint_val), &uint_val, NULL); printf(" Max Work Item Dimensions: %u\n", uint_val); clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_ITEM_SIZES, sizeof(size_val), &size_val, NULL); printf(" Max Work Item Sizes: [%zu, %zu, %zu]\n", size_val[0], size_val[1], size_val[2]); clGetDeviceInfo(device, CL_DEVICE_VERSION, sizeof(buffer), buffer, NULL); printf(" OpenCL Version: %s\n", buffer); clGetDeviceInfo(device, CL_DEVICE_EXTENSIONS, sizeof(buffer), buffer, NULL); printf(" Extensions: %s\n", buffer); clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT, sizeof(uint_val), &uint_val, NULL); printf(" Preferred Float Vector Width: %u\n", uint_val); clGetDeviceInfo(device, CL_DEVICE_IMAGE_SUPPORT, sizeof(bool_val), &bool_val, NULL); printf(" Image Support: %s\n", bool_val ? "YES" : "NO"); clGetDeviceInfo(device, CL_DEVICE_DOUBLE_FP_CONFIG, sizeof(fp_config), &fp_config, NULL); printf(" Double FP Support: %s\n", (fp_config != 0) ? "YES" : "NO"); printf("\n"); } int main() { cl_uint num_platforms; cl_platform_id platforms[10]; clGetPlatformIDs(10, platforms, &num_platforms); for (cl_uint i = 0; i < num_platforms; i++) { char name[256]; clGetPlatformInfo(platforms[i], CL_PLATFORM_NAME, sizeof(name), name, NULL); printf("Platform: %s\n", name); cl_uint num_devices; cl_device_id devices[10]; clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_ALL, 10, devices, &num_devices); for (cl_uint j = 0; j < num_devices; j++) { print_device_info(devices[j]); } } return 0; } ===== Wynik ===== {{ :public:wikiblog:22-05-2025-6.png?direct |}} ===== Dodatkowe informacje ===== W przypadku przenoszenia binarki na inną platformę, proponuję dorzucić plik ''OpenCL.dll'' z katalogu ''bin'' obok pliku ''exe''. Zagwarantuje to obecność biblioteki w wersji, z którą skompilowano kod. W celu zapoznania się z programowaniem w OpenCL, polecam następującą prezentację: [[https://agenda.infn.it/event/14351/contributions/24177/attachments/17206/19529/OpenCL_programming.pdf]]. ({{ :public:wikiblog:opencl_programming.pdf | OpenCL_programming.pdf - Kopia}}) W wielu przykładach z OpenCL 2.0 widnieje zawołanie do funkcji ''clCreateCommandQueue'' która jest przestarzała. Zamiast tego, należy użyć ''clCreateCommandQueueWithProperties'' ([[https://registry.khronos.org/OpenCL/sdk/2.0/docs/man/xhtml/clCreateCommandQueueWithProperties.html|Dokumentacja]], [[https://stackoverflow.com/a/28500846|StackOverflow]]). [[https://registry.khronos.org/OpenCL/specs/3.0-unified/html/OpenCL_C.html|Specyfikacja dla kernela.]]