Friday, November 13, 2015

A text file is stored in a distributed manner on three hard disks on three machines such that consecutive lines, one per hard disk are stored in cyclic manner. Write a program using OpenCL to read/Write/Modify the file.

PROGRAM

b12.c

#include <stdio.h>
#include <stdlib.h>
#include <CL/cl.h>
#include <string.h>
#define SRC_SIZE (0x100000)

int total_lines()
{
    FILE * fp;
    char s[50];
    int line = 0;
    fp = fopen("file1.txt", "r");
    while(!feof(fp))
    {
        fgets(s, 50, fp);
        line++;
    }
    fclose(fp);
    fp = fopen("file2.txt", "r");
    while(!feof(fp))
    {
        fgets(s, 50, fp);
        line++;
    }
    fclose(fp);
    fp = fopen("file3.txt", "r");
    while(!feof(fp))
    {
        fgets(s, 50, fp);
        line++;
    }
    line  -= 6;
    fclose(fp);
    return line;
}

int main()
{
    cl_device_id device_id = NULL;
    cl_context context = NULL;
    cl_command_queue command_queue = NULL;
    cl_program program = NULL;
    cl_kernel kernel = NULL;
    cl_platform_id platform_id = NULL;
    cl_uint num_devices, num_platforms;
    cl_mem buff1 = NULL, buff2 = NULL, x = NULL, l = NULL;
    size_t gl = 3, lo = 1;
     
    FILE *fp = fopen("./b12.cl", "r");
    if(!fp) 
    {
        printf("Failed to load kernel.\n");
        exit(1);
    }
    char * src = (char*)malloc(SRC_SIZE);
    size_t src_size = fread(src, 1, SRC_SIZE, fp);
    fclose(fp);
    
    clGetPlatformIDs(1, &platform_id, &num_platforms);
    clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_DEFAULT, 1, &device_id, &num_devices);
    context = clCreateContext(NULL, 1, &device_id, NULL, NULL, NULL); 
    command_queue = clCreateCommandQueue(context, device_id, 0, NULL); 
    
    buff1 = clCreateBuffer(context, CL_MEM_READ_WRITE, 50*sizeof(char), NULL, NULL);
    buff2 = clCreateBuffer(context, CL_MEM_READ_WRITE, 50*sizeof(char), NULL, NULL);
    x = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(int), NULL, NULL);
    l = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(int), NULL, NULL);
    
    program = clCreateProgramWithSource(context, 1, (const char **)&src, (const size_t *)&src_size, NULL); 
    clBuildProgram(program, 1, &device_id, NULL, NULL, NULL);
    kernel = clCreateKernel(program, "b12", NULL);
   
    while(1)
    {
        int choice = 0, line = 0;
        char s[50];
         
        printf("1. Read\t2. Write\t3. Exit\n");
        scanf("%d", &choice);

        switch(choice)
        {
            case 1:
                printf("Enter line number: ");
                scanf("%d", &line);
                if (line > total_lines())
                {
                    printf("Invalid line number\n");
                    continue;    
                }
                break;
                
            case 2:
                printf("Enter line to write: ");
                scanf("%s", s);
                clEnqueueWriteBuffer(command_queue, buff2, CL_TRUE, 0, 50, s, 0, NULL, NULL);
                line = total_lines();
                break;
            case 3:
                exit(0);
                
            default:
                printf("Wrong option!\n");
                continue;
        }   
        switch(line%3)
        {
            case 0:
                fp = fopen("file1.txt", "r");
                fread(s, 50, 1, fp);
                clEnqueueWriteBuffer(command_queue, buff1, CL_TRUE, 0, strlen(s), s, 0, NULL, NULL);
                fclose(fp);
                break;
            
            case 1:
                fp = fopen("file2.txt", "r");
                fread(s, 50, 1, fp);
                clEnqueueWriteBuffer(command_queue, buff1, CL_TRUE, 0, strlen(s), s, 0, NULL, NULL);
                fclose(fp);
                break;
            
            case 2:
                fp = fopen("file3.txt", "r");
                fread(s, 50, 1, fp);
                clEnqueueWriteBuffer(command_queue, buff1, CL_TRUE, 0, strlen(s), s, 0, NULL, NULL);
                fclose(fp);          
                break;
        }
        
        clEnqueueWriteBuffer(command_queue, x, CL_TRUE, 0, sizeof(int), &choice, 0, NULL, NULL);
        clEnqueueWriteBuffer(command_queue, l, CL_TRUE, 0, sizeof(int), &line, 0, NULL, NULL);
        clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&buff1);
        clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&buff2);
        clSetKernelArg(kernel, 2, sizeof(cl_mem), (void *)&x);
        clSetKernelArg(kernel, 3, sizeof(cl_mem), (void *)&l);
        clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL, &gl, &lo, 0, NULL, NULL);
        
        switch(choice)
        {
            case 1:
                clEnqueueReadBuffer(command_queue, buff2, CL_TRUE, 0, 50, s, 0, NULL, NULL);
                printf("%s\n", s);
                break;
                
            case 2:
                line++;
                clEnqueueReadBuffer(command_queue, buff1, CL_TRUE, 0, 50, s, 0, NULL, NULL);
                switch(line%3)
                {
                case 0:
                    fp = fopen("file3.txt", "w");
                    fwrite(s, 1, strlen(s), fp);
                    fclose(fp);
                    break;
                
                case 1:
                    fp = fopen("file1.txt", "w");
                    fwrite(s, 1, strlen(s), fp);
                    fclose(fp);
                    break;
            
                case 2:
                    fp = fopen("file2.txt", "w");
                    fwrite(s, 1, strlen(s), fp);
                    fclose(fp);          
                    break;
                }
                break;
        }   
    }  
    
    clFlush(command_queue);
    clFinish(command_queue);
    clReleaseKernel(kernel);
    clReleaseProgram(program);
    clReleaseMemObject(buff1);
    clReleaseMemObject(buff2);
    clReleaseMemObject(x);
    clReleaseMemObject(l);
    clReleaseCommandQueue(command_queue);
    clReleaseContext(context);
    free(src);
    return 0;

}

b12.cl

void readline(__global char * buff1, __global char * buff2, __global int * l)
{
    int i=0, j=0, k=0, line = (*l)/3;
    while(j < line)
    {
        if(buff1[i] == '\n')
            j++;
        i++;
    }
    while(buff1[i] != '\n' && buff1[i] != '\0')
    {
        buff2[k] = buff1[i];
        i++;
        k++;
    }
}

void writeline(__global char * buff1, __global char * buff2,__global int *l)
{
    int i=0, j=0;
    while(buff1[i]!='\0')
        i++;
    do
    {
        buff1[i] = buff2[j];
        i++;
        j++;
    }while(buff2[j]!='\0');   
}

__kernel void b12(__global char * buff1, __global char * buff2, __global int * x, __global int * l)
{
int i = get_global_id(0);
    if(i != (*l)%3)
         return;
    if(*x == 1)
        readline(buff1, buff2, &l[0]);
    else if(*x == 2)
        writeline(buff1, buff2,&l[0]);
}

No comments:

Post a Comment

Perform a suitable assignment using Xen Hypervisor or equivalent open source to configure it. Give necessary GUI.

 To install kvm on Fedora:  yum install kvm  yum install virt-manager libvirt libvirt-python python-virtinst  su -c "yum install @v...