User Tools

Site Tools


public:wikiblog:22-05-2025-srodowisko-opencl-visual-studio-2022

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 “<nazwa-projektu> Debug Properties”.

Rozwiń pole “Configuration” i zmień opcję na “All Configurations”.

W zakładce “C/C++”, dodaj ścieżkę do katalogu “include” w opcji “Additional Include Directories”.

W zakładce “Linker”, dodaj ścieżkę do katalogu “lib” w opcji “Additional Library Directories”.

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;.

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 <CL/cl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
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

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. ( 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 (Dokumentacja, StackOverflow).

Specyfikacja dla kernela.

public/wikiblog/22-05-2025-srodowisko-opencl-visual-studio-2022.txt · Last modified: 2025/05/21 23:48 by mdukat