How to read txt file in OpenCL

1.5k views Asked by At

I'm new to OpenCL. Does anybody know how to read a text file through OpenCL? Because I want to be able to read the file and split the content into some arrays. For the example, I have txt file consists: 1010101 1 1010111. I want to get 1010101 as array a and 1010111 as array b. Here, we see a tab/space, it has tab delimiter with "1", so I need to split with delimiter "\t1" as well.

Here my the main code:

for (int i = 0; i < N; i++) { 

            System.out.println("perturb node: "+i);
            cs=calcDistanceCs();//ok
            System.out.println("csTemp: "+Arrays.toString(cs));
            //System.out.println("csTemp: "+cs); 
            for (int j = 0; j < N; j++) {

                if (j!=i) {
                    System.out.println("target node: "+j);
                    nTarget=j;
                    rs=calcDistanceRs();

                    System.out.println("rsTemp: "+Arrays.toString(rs));

                    //System.out.println("rsTemp: "+rs);

                    eff=dtmp/numofRStates;
                    System.out.println("Effectiveness "+eff);

                    //print-out result
                    pw.println(i+"\t"+eff+"\t"+j);
                    // flush the writer
                    pw.flush();
                } 
            }
        }
        Pointer srcA = Pointer.to(cs);
        Pointer srcB = Pointer.to(rs);
        //Pointer dst = Pointer.to(resultArr);

        // The platform, device type and device number
        final int platformIndex = 0;
        final long deviceType = CL_DEVICE_TYPE_ALL;
        final int deviceIndex = 0;

        // Enable exceptions and subsequently omit error checks in this sample
        CL.setExceptionsEnabled(true);

        // Obtain the number of platforms
        int numPlatformsArray[] = new int[1];
        clGetPlatformIDs(0, null, numPlatformsArray);
        int numPlatforms = numPlatformsArray[0];

        //obtain a platform id
        System.out.println("Obtaining platform..."); //running, muncul
        cl_platform_id platforms[] = new cl_platform_id[numPlatforms];
        clGetPlatformIDs(platforms.length, platforms, null);
        cl_platform_id platform = platforms[platformIndex];
        System.out.println("Platform id: "+platform); //uda langsung ke string tanpa harus diconvert

        //Initialize the context properties
        cl_context_properties contextProperties = new cl_context_properties();
        contextProperties.addProperty(CL_CONTEXT_PLATFORM, platform);        

        // Obtain the number of devices for the platform
        int numDevicesArray[] = new int[1];
        clGetDeviceIDs(platform, deviceType, 0, null, numDevicesArray);
        int numDevices = numDevicesArray[0];

        // Obtain a device ID 
        cl_device_id devices[] = new cl_device_id[numDevices];
        clGetDeviceIDs(platform, deviceType, numDevices, devices, null);
        cl_device_id device = devices[deviceIndex];

        // Create a context for the selected device
        cl_context context = clCreateContext(contextProperties, 1, new cl_device_id[]{device},null, null, null);  
        //create an opencl context on a gpu device
        //cl_context context=clCreateContextFromType(contextProperties,CL_DEVICE_TYPE_GPU,null,null,null);
        if (context==null) {
            /*if no context for a gpu device could be created,
            try to create one for a cpu device
            */
            System.out.println("Cannot create GPU context...");
            context=clCreateContextFromType(contextProperties, CL_DEVICE_TYPE_CPU, null, null, null);
            if (context==null) {
                System.out.println("Unable to create a context");
                return;
            }else{
                System.out.println("Successfully created CPU context ^^");
            }
        }else{
            System.out.println("Successfully created GPU context...");
        }

        // Create a command-queue for the selected device
        cl_command_queue commandQueue = clCreateCommandQueue(context, device, 0, null);

        // Allocate the memory objects for the input- and output data
        cl_mem memObjects[] = new cl_mem[2];
        memObjects[0] = clCreateBuffer(context, 
                CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
                Sizeof.cl_char * N, srcA, null);
        memObjects[1] = clCreateBuffer(context, 
                CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
                Sizeof.cl_char * N, srcB, null);
        /*            memObjects[2] = clCreateBuffer(context,
        CL_MEM_READ_WRITE,
        Sizeof.cl_float * N, null, null);*/

        // Create the program from the source code

        System.out.println("Reading file from kernels...");
        String programSource=readFile("kernel_/CalEff.cl"); //membaca file dari luar folder src--sukses ^^

        //create the program from the source code 
        cl_program program=clCreateProgramWithSource(context,1,new String[]{programSource},null,null);        

        // Build the program
        clBuildProgram(program, 0, null, null, null, null);

        // Create the kernel
        cl_kernel kernel = clCreateKernel(program, "Effectiveness", null); //nama procedure yg dipanggil di kernel/opencl

        // Set the arguments for the kernel -->kernel, arg index,long arg size, pointer
        clSetKernelArg(kernel, 0, Sizeof.cl_mem, Pointer.to(memObjects[0]));//jumlahnya ada 3 cz yg dideklarasi jg ada3
        clSetKernelArg(kernel, 1, Sizeof.cl_mem, Pointer.to(memObjects[1]));
        clSetKernelArg(kernel, 2, Sizeof.cl_mem, Pointer.to(memObjects[2]));

        // Set the work-item dimensions
        long global_work_size[] = new long[]{N};
        long local_work_size[] = new long[]{1};//This means each item is a separate workgroup

        // Execute the kernel
        clEnqueueNDRangeKernel(commandQueue, kernel, 1, null,global_work_size, local_work_size, 0, null, null); //execure each array in parallel

        // Read the output data-->from c parameter /kalo dibutuhkan
        //clEnqueueReadBuffer(commandQueue, memObjects[2], CL_TRUE, 0,N * Sizeof.cl_float, dst, 0, null, null);
        /*BASIC END HERE*/

        // Release kernel, program, and memory objects
        clReleaseMemObject(memObjects[0]);
        clReleaseMemObject(memObjects[1]);
        clReleaseMemObject(memObjects[2]);
        clReleaseKernel(kernel);
        clReleaseProgram(program);
        clReleaseCommandQueue(commandQueue);
        clReleaseContext(context);

But for calcDistanceCs() and calcDistanceRs() they both need to read a txt file. Then from that file i got the array (stateArray[]) like this:

    FileReader fr;
    LineNumberReader lnr; 
    String str;
    int i;
    System.out.println("Calculate distance Current State: ");
    try{
        // create new reader
        fr = new FileReader("AttractorCs.txt");
        lnr = new LineNumberReader(fr);

        csLine=0;
        // read lines till the end of the stream
        while((str=lnr.readLine())!=null){
            i=lnr.getLineNumber();

            csBariske=i;
            csBaris=str;

            if(csBaris!=null){
                List<ModEff> listState= new LinkedList<>();
                String[] stateArray;            
                stateArray=csBaris.split("\t");

                node1=BinaryStringtoBinaryByteArrAwal(stateArray[0]);
                node2=BinaryStringtoBinaryByteArrAkhir(stateArray[2]);

            }
            if (csBariske % 2 == 1) {
                it_attcGanj=String.valueOf(node1)+String.valueOf(node2);  
            }else{
                it_attcGen=String.valueOf(node2)+String.valueOf(node1);

                it_att=it_attcGanj+it_attcGen;
                nodeCsArr = convertNodeArrToByteArr(it_att); 
            }
            csLine++;
        }

        lnr.close();
    }catch(Exception e){

       // if any error occurs
       e.printStackTrace();
    }
    System.gc();
    return nodeCsArr;

Here the example text file that I need to read: 00010000000000000000000000001000000000000000000000110000000001000000000010010111000000000000000000100000000000000001001000000000000000000000000000000001000000000000000000000000100000100000000000001000000000000001010000000000010000000000000000001000000000000001000000001000001100101000000000000010000000000010000000000000000000000000010000000000000110000000000001000000000000000000000100000000001001001110010000000000000000100000000000000000001000000000010000000010000000010000000000000000000010000000000100110000001000000000000000000000000001000000000000000100000000000100000000000000000000010000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000010000000000000000100000110000000000000000000000000000000010000000000000000000010000000000000000000000100 1 00010000000000000000000000001000000000000000000000010000000001000000000000010011000000000000000000100000000000000001001000000000000000000000000000000001000000000000000000000000100000100000000000001000000000000001010000000000010000000000000000001000000000000001000000001000001100001000000000000010000000000010000000000000000000000000010000000000000110000000000001000000000000000000000100000000001001001110000000000000000000100000000000000000001000000000010000000010000000010000000000000000000000000000000100110000001000000000000000000000000001000000000000000100000000000100000000000000000000010000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000010000000000000000100000110000000000000000000000000000000010000000000000000000010000000000000000000000100

From example above, I want to split to: 1st array: 00010000000000000000000000001000000000000000000000110000000001000000000010010111000000000000000000100000000000000001001000000000000000000000000000000001000000000000000000000000100000100000000000001000000000000001010000000000010000000000000000001000000000000001000000001000001100101000000000000010000000000010000000000000000000000000010000000000000110000000000001000000000000000000000100000000001001001110010000000000000000100000000000000000001000000000010000000010000000010000000000000000000010000000000100110000001000000000000000000000000001000000000000000100000000000100000000000000000000010000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000010000000000000000100000110000000000000000000000000000000010000000000000000000010000000000000000000000100 2nd array: 00010000000000000000000000001000000000000000000000110000000001000000000010010111000000000000000000100000000000000001001000000000000000000000000000000001000000000000000000000000100000100000000000001000000000000001010000000000010000000000000000001000000000000001000000001000001100101000000000000010000000000010000000000000000000000000010000000000000110000000000001000000000000000000000100000000001001001110010000000000000000100000000000000000001000000000010000000010000000010000000000000000000010000000000100110000001000000000000000000000000001000000000000000100000000000100000000000000000000010000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000010000000000000000100000110000000000000000000000000000000010000000000000000000010000000000000000000000100

each arrays consist of 800 bytes(from array 0-799). The separator(delimiter), I make it bold 1.

1

There are 1 answers

1
paulsm4 On BEST ANSWER

If I'm understanding your question correctly, it looks like you want to read a fixed width flat file.

Strong suggesion: consider using a library, like flatpack: http://flatpack.sourceforge.net/

Here are a few other links that might help:

1) So apparently you've got a "tab delimited file". OK - you can definitely split it into an array of strings with String.split("\t").

2) In your example example:

I have txt file consists: 1010101 1 1010111. I want to get 1010101 as array a and 1010111 as array b.

If the delimiter is always "\t1", that will work. If the delimiter might be "\t2", or "\t1000", then you might want to:

  • Use String.split("\t")

  • In your example, it will give you three arrays: "1010101", "1010101" ... and "1".

  • Parse "array[1]" (the value "1") accordingly.

3) I'm not sure what you mean by "array".

In your example, the values "1010101" and "1010101" will be two elements in ONE, SINGLE array.

But this shouldn't be a problem: you can always use myArray[n].charAt(i).

Or, alternatively, you can always convert the string into a character array:

char[] charArray = myArray[n].toCharArray();