Perbaiki diagram blok program opencl dan mungkin program itu sendiri

pemrograman


Buat program menggunakan OpenCL dan menggunakan memori lokal. Tugas: b=min(A+C)

Saya memiliki diagram blok yang sudah jadi, tetapi guru mengatakan bahwa diagram tersebut menunjukkan semuanya secara berurutan, dan kami memiliki program paralel dan saya tidak tahu cara memperbaiki diagram blok.

Saya juga ingin tahu apakah saya telah menulis program menggunakan memori lokal dengan benar atau tidak.

Tautan ke gambar dengan diagram blok: https://www.imghippo.com/i/1704956923.jpg

#define _CRT_SECURE_NO_WARNINGS
#define CL_USE_DEPRECATED_OPENCL_1_2_APIS
#include <CL/cl.h>
#include <CL/cl_platform.h>
#include <iostream>
#include <cstdlib>
#include <stdio.h>

#define MAX_SOURCE_SIZE (0x100000)
#define LIST_SIZE 64

int main(void) {
    int* A = new int[LIST_SIZE];
    int* C = new int[LIST_SIZE];
    int* B = new int[LIST_SIZE];
    srand(time(0));
    for (int i = 0; i < LIST_SIZE; i++) {
        A[i] = (rand() % 200) / 2.;
        C[i] = (rand() % 200) / 2.;
    }

    FILE* fp;
    char* source_str;
    size_t source_size;

    fp = fopen("kernel.cl", "r");
    if (!fp) {
        fprintf(stderr, "Failed to load kernel.\n");
        exit(1);
    }
    source_str = new char[MAX_SOURCE_SIZE];
    source_size = fread(source_str, 1, MAX_SOURCE_SIZE, fp);
    fclose(fp);

    cl_platform_id platform_id = NULL;
    cl_device_id device_id = NULL;
    cl_uint ret_num_devices;
    cl_uint ret_num_platforms;
    cl_int ret = clGetPlatformIDs(1, &platform_id, &ret_num_platforms);
    ret = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_DEFAULT, 1, &device_id, &ret_num_devices);

    cl_context context = clCreateContext(NULL, 1, &device_id, NULL, NULL, &ret);

    cl_command_queue command_queue = clCreateCommandQueueWithProperties(context, device_id, 0, &ret);

    cl_mem a_mem_obj = clCreateBuffer(context, CL_MEM_READ_ONLY, LIST_SIZE * sizeof(int), NULL, &ret);
    cl_mem c_mem_obj = clCreateBuffer(context, CL_MEM_READ_ONLY, LIST_SIZE * sizeof(int), NULL, &ret);
    cl_mem b_mem_obj = clCreateBuffer(context, CL_MEM_WRITE_ONLY, LIST_SIZE * sizeof(int), NULL, &ret);

    ret = clEnqueueWriteBuffer(command_queue, a_mem_obj, CL_TRUE, 0, LIST_SIZE * sizeof(int), A, 0, NULL, NULL);
    ret = clEnqueueWriteBuffer(command_queue, c_mem_obj, CL_TRUE, 0, LIST_SIZE * sizeof(int), C, 0, NULL, NULL);

    cl_program program = clCreateProgramWithSource(context, 1, (const char**)&source_str, (const size_t*)&source_size, &ret);

    ret = clBuildProgram(program, 1, &device_id, NULL, NULL, NULL);

    cl_kernel kernel = clCreateKernel(program, "krn", &ret);

    size_t local_item_size = 64;
    ret = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void*)&a_mem_obj);
    ret = clSetKernelArg(kernel, 1, sizeof(cl_mem), (void*)&c_mem_obj);
    ret = clSetKernelArg(kernel, 2, sizeof(cl_mem), (void*)&b_mem_obj);
    ret = clSetKernelArg(kernel, 3, local_item_size * sizeof(int), NULL);

    size_t global_item_size = LIST_SIZE;
    ret = clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL, &global_item_size, &local_item_size, 0, NULL, NULL);

    ret = clEnqueueReadBuffer(command_queue, b_mem_obj, CL_TRUE, 0, LIST_SIZE * sizeof(int), B, 0, NULL, NULL);

    for (int i = 0; i < LIST_SIZE; i++) {
        printf("%d. sum: %d\n", i, B[i]);
    }

    int min = B[0];
    int minIndex = 0;
    for (int i = 0; i < LIST_SIZE; i++) {
        if (B[i] < min) {
            min = B[i];
            minIndex = i;
        }
    }
    printf("\n\n%d. Minimum min(A+C) = %d\n", minIndex, min);

    ret = clFlush(command_queue);
    ret = clFinish(command_queue);
    ret = clReleaseKernel(kernel);
    ret = clReleaseProgram(program);
    ret = clReleaseMemObject(a_mem_obj);
    ret = clReleaseMemObject(c_mem_obj);
    ret = clReleaseMemObject(b_mem_obj);
    ret = clReleaseCommandQueue(command_queue);
    ret = clReleaseContext(context);
    delete[] source_str;
    delete[] A;
    delete[] B;
    delete[] C;
    return 0;
}

kernel.cl:

__kernel void krn(__global const int* A, __global const int* C, __global int* B) {
    int i = get_global_id(0); 
    __local int localA[128];
    __local int localC[128];
    localA[i] = A[i];
    localC[i] = C[i];
    barrier(CLK_LOCAL_MEM_FENCE);
    B[i] = localA[i] + localC[i];
}

Apa yang saya coba:

Membuat diagram blok yang salah dan menulis sebuah program

Solusi 1

A.Tidak.

Itu bukan diagram tentang cara kerja aplikasi Anda: ini adalah campuran aplikasi dan instruksi untuk memproduksinya – dan jika tugas Anda ingin Anda membuat aplikasi berbasis paralel, maka Anda perlu memeriksa tugas tersebut dengan cermat dan mengidentifikasi bagian mana yang bisa dilakukan secara bersamaan dan mandiri, yang tidak tercakup dalam diagram saat ini sama sekali.

Sejujurnya? Saya akan menghapus semua yang telah Anda lakukan sejauh ini, memulai lagi dengan kertas kosong, dan membaca kembali catatan/materi mata kuliah Anda dari awal, karena sepertinya Anda belum memahami banyak hal sejauh ini. Dan sangat penting bagi Anda untuk memahami perbedaan antara serial dan paralel, dan bahkan antara aplikasi dan tindakan membuat aplikasi – keduanya bukanlah hal yang sama.

Jangan terburu-buru membuat kode: pikirkan dulu dan Anda akan menghemat banyak waktu yang terbuang.

コメント

タイトルとURLをコピーしました