我正在尝试使用OpenCL在c语言中进行vigenere加密算法,我没有OpenCL的经验。我正在使用Mac OS(因此我正在运行OpenCL 1.2或1.1)并使用Makefile构建程序。该文件已编译,但输出不是我期望的。
当前问题的示例:
期望:
如果有人可以告诉我我做错了,我将非常感激。
这是我的C代码:
#include <stdio.h> #include <stdlib.h> #include <OpenCL/opencl.h> #define CL_USE_DEPRECATED_OPENCL_1_2_APIS #define MY_CL_GPU 1 #define MY_CL_CPU 0 #define ENCRYPT 'E' #define DECRYPT 'D' #define IO_MESAGE #define IO_KEY #define MAX_SOURCE_SIZE (0x100000) void IO_selected_mode( char* program_opreation ); int IO_get_mesage( char* mesage ); void normalize_key( char* key, int key_size, int mesage_size ); int main(){ //int compute_unit = MY_CL_CPU; int compute_unit = MY_CL_GPU; char name[128]; dispatch_queue_t queue; if ( compute_unit == MY_CL_GPU ){ queue = gcl_create_dispatch_queue(CL_DEVICE_TYPE_GPU, NULL); }else{ queue = gcl_create_dispatch_queue(CL_DEVICE_TYPE_CPU, NULL); } if ( queue == NULL ) { printf("\nCan't find OpenCL copute unit"); } cl_device_id device_id = gcl_get_device_id_with_dispatch_queue(queue); clGetDeviceInfo( device_id, CL_DEVICE_NAME, 128, name, NULL); printf("Created a dispatch queue using the %s\n\n", name); char program_opreation = '0'; IO_selected_mode( &program_opreation ); printf("\nInput mesage:"); char* mesage = NULL;// = malloc( 100 * sizeof(char) ) ; int mesage_size; mesage_size = IO_get_mesage( mesage ); printf("\nInput key:"); char* key = NULL;// = malloc( 100 * sizeof(char) ) ; int key_size; key_size = IO_get_mesage( key ); normalize_key( key, key_size, mesage_size ); char* output; int output_size; output = malloc( mesage_size * sizeof(char) ); output_size = mesage_size; int mesage_data_size = mesage_size * sizeof(char); FILE* fp; char* source_str; size_t source_size; fp = fopen( "mykernel.cl", "r" ); if (!fp) { fprintf(stderr, "Failed to load kernel.\n"); exit(1); } source_str = (char*)malloc(MAX_SOURCE_SIZE); source_size = fread(source_str, 1, MAX_SOURCE_SIZE, fp); fclose(fp); cl_int ret; cl_context context = clCreateContext( NULL, 1, &device_id, NULL, NULL, &ret); cl_command_queue command_queue = clCreateCommandQueue( context, device_id, 0, &ret ); cl_mem mesage_mem_obj = clCreateBuffer(context, CL_MEM_READ_ONLY, mesage_data_size, NULL, &ret); cl_mem key_mem_obj = clCreateBuffer(context, CL_MEM_READ_ONLY, mesage_data_size, NULL, &ret); cl_mem output_mem_obj = clCreateBuffer(context, CL_MEM_READ_ONLY, mesage_data_size, NULL, &ret); // Copy the lists A and B to their respective memory buffers ret = clEnqueueWriteBuffer(command_queue, mesage_mem_obj, CL_TRUE, 0, mesage_data_size, mesage, 0, NULL, NULL); ret = clEnqueueWriteBuffer(command_queue, key_mem_obj, CL_TRUE, 0, mesage_data_size, key, 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; if( program_opreation == ENCRYPT ) { kernel = clCreateKernel(program, "Encrypt_module", &ret); } if( program_opreation == DECRYPT ) { kernel = clCreateKernel(program, "Decrypt_module", &ret); } ret = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void*)&mesage_mem_obj); ret = clSetKernelArg(kernel, 1, sizeof(cl_mem), (void*)&key_mem_obj); ret = clSetKernelArg(kernel, 2, sizeof(cl_mem), (void*)&output_mem_obj); size_t global_item_size[1]; global_item_size[0] = mesage_size; ret = clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL, global_item_size, NULL, 0, NULL, NULL); ret = clEnqueueReadBuffer(command_queue, output_mem_obj, CL_TRUE, 0, output_size, output, 0, NULL, NULL); if( program_opreation == ENCRYPT ) { printf("\nThe Encrypted mesage is:\n>>>%s\n", output); } else if( program_opreation == DECRYPT ) { printf("\nThe Decrypted mesage is:\n>>>%s\n", output); } return 0; } void IO_selected_mode( char* program_opreation ){ printf("\nSelect mode: for Encryption press 'E' ; for Decription press D \n>>>"); scanf( "%c", program_opreation ); } int IO_get_mesage( char* mesage ){ mesage = malloc( sizeof(char) ); char c = 'a'; int size = 0; printf("\n>>>"); getc(stdin); //Posibil BUG while( c != '\n' ){ size++; c = getc( stdin ); mesage = (char*)realloc( mesage, size * sizeof(char) ); mesage[ size ] = c; } return size ; } void normalize_key( char* key, int key_size, int mesage_size ){ key = (char*)realloc( key, mesage_size * sizeof(char) ); int i, j; for( i = 0, j = 0; i < mesage_size; i++, j++ ){ if(j == key_size - 1 ) j = 0; key[i] = key[j]; } }
这是我的内核代码:
__kernel void Encrypt_module(__global const char* mesage, __global const char* key, __global char* encrypted_message) { int i = get_global_id(0); int mesage_size = get_global_size(0); char key_inter = key[i] - 'a'; char mesage_inter = encrypted_message[i] - 'a'; if( mesage[i] == ' ' ) { encrypted_message[i]=mesage[i]; } else { mesage_inter = ( mesage_inter + key_inter ) % 26; encrypted_message[i] = mesage_inter + 'a'; } } __kernel void Decrypt_module(__global const char* encrypted_message, __global const char* key, __global int* decrypted_message) { int i = get_global_id(0); int mesage_size = get_global_size(0); if( encrypted_message[i] == ' ' ) { decrypted_message[i] = encrypted_message[i]; } else { decrypted_message[i] = ( ( encrypted_message[i] - key[i] + 26 ) % 26 ) + 'a'; } }
这是我的Makefile:
OPENCLC=/System/Library/Frameworks/OpenCL.framework/Libraries/openclc
BUILD_DIR=./build
EXECUTABLE=main
.SUFFIXES:
KERNEL_ARCH=i386 x86_64 gpu_32 gpu_64
BITCODES=$(patsubst %, mykernel.cl.%.bc, $(KERNEL_ARCH))
$(EXECUTABLE): $(BUILD_DIR)/mykernel.cl.o $(BUILD_DIR)/main.o $(BITCODES)
clang -framework OpenCL -o $@ $(BUILD_DIR)/mykernel.cl.o $(BUILD_DIR)/main.o
$(BUILD_DIR)/mykernel.cl.o: mykernel.cl.c
mkdir -p $(BUILD_DIR)
clang -c -Os -Wall -arch x86_64 -o $@ -c mykernel.cl.c
$(BUILD_DIR)/main.o: main.c mykernel.cl.h
mkdir -p $(BUILD_DIR)
clang -c -Os -Wall -arch x86_64 -o $@ -c $<
mykernel.cl.c mykernel.cl.h: mykernel.cl
$(OPENCLC) -x cl -cl-std=CL1.1 -cl-auto-vectorize-enable -emit-gcl $<
mykernel.cl.%.bc: mykernel.cl
$(OPENCLC) -x cl -cl-std=CL1.1 -Os -arch $* -emit-llvm -o $@ -c $<
.PHONY: clean
clean:
rm -rf $(BUILD_DIR) mykernel.cl.h mykernel.cl.c $(EXECUTABLE) *.bc
run:
./main
我正在尝试使用OpenCL在c语言中进行vigenere加密算法,我没有OpenCL的经验。我正在使用Mac OS(因此我正在运行OpenCL 1.2或1.1)并使用Makefile构建程序。 ...
我已经完成了程序,它可以在这里链接:https://github.com/cosmineala/vigenere_C_OpenCL