Counting entries in Excel table

The execution time is roughly the same. This has at least two reasons:

  • The data set is rather small (reading the file and creating the ‘count’ table probably takes longer than the computation)
  • The implementation is in no way optimized, but only a first test

I only replaced the main computation (getTwoTailedP) with a CUDA version. The .cu file contains the CUDA kernel, and it is (at the moment) basically the Java function simply ported to CUDA.

In both cases (Java and CUDA) it creates an array of ‘tasks’. Each ‘task’ consists of 4 elements. These are the entries of the ‘count’ table for which it should compute the TwoTailedP. This array is passed to the Java- or the CUDA function, and it computes a ‘result’ for each task.

The CUDA file (.CU) is converted into a PTX file each time the program is started. But of course, when the program and the CUDA implementation are finished and the CUDA file does not change any more, one can use always the same PTX file and it does not have to be created again each time.

An update. Still a fairly simple implementation, but in contrast to the first one, the logarithmic factorials are not computed on the fly for each call, but instead precomputed (as it was done in the ‘f’-array in the Java version). Now it’s approximately 10 times faster than the Java version.
Of course, it could be optimized further.
But may I ask in which context you need this program? If it’s only about the results, you might consider using http://www.r-project.org/ or a sophisticated implementation of “FEXACT”…

Hi Marco. I have to do this as a project for a degree (end of July if all goes well). I don’t know exactly what they want but just say me that i should implements the Fisher Test class write in pure java, in CUDA/JCuda (this because i have chose this) to get better performance than traditional computing (done with FisherTest class). That’s all: they didn’t say „exactly“ what i have to do (in fact, i didn’t realize it myself) just „to do“ (in fact, all your questions, i asked them). Now that the project is almost complete, i should let them see (maybe the next update): if it’s ok, well done (but i don’t know what they’ll answer to me :frowning: ).
Thanks Marco for all your precious help until now, without which i wouldn’t have never done.

Well, the intention of such a thesis is not to ask for a solution in a forum… -_- However, if you have further, specific questions, I’ll try to answer them.

I know Marco but, as i wrote earlier, for me is impossible (for my fault but not only). If you want to continue to help me, i’ll be grateful to you, otherwise worse for me.

Of course I’ll try to help you. But I won’t do everything. And more importantly: There is no predefined “end”. Now, the CUDA implementation is faster than the Java implementation. But of course, there are many possible improvements. During my websearches I found “FEXACT: A FORTRAN subroutine for Fisher’s Exact Test (Mehta and Patel)”, which one could have a closer look at. If could be algorithmically cheaper, so that, for example, a Java implementation of FEXACT might be faster than even the fastest CUDA implementation of the current, naive approach. And even for the current, naive implementation, one could consider loading the required elements of the ‘logFactorials’ into shared memory, which might bring another speedup. But at some point, this becomes too much for me to do it for free and in my spare time…

Ok Marco, you’re right. Now i have one question: in the last update are shown only the first row: how can i show all rows ? Thanks.

Do you mean the 10 rows that are printed with

        //*/
        for (int i=0; i<10; i++)
        {
            int h0 = tasks[i*4+0];
            int h1 = tasks[i*4+1];
...

You can change this to

        //*/
        for (int i=0; i<t; i++) // t is the number of tasks
        {
            int h0 = tasks[i*4+0];
            int h1 = tasks[i*4+1];

Ok. So if the file have almost 2000 row i have to write 2000, right ?

Note that this is not the number of rows in one of the input tables. The variable ‘t’ (sorry, it’s a stupid name :o ) stands for the number of “tasks”. Each task contains the 4 elements of a 2x2-Table for which the TwoTailedP should be computed. Thus, ‘t’ is not known at the beginning, but only after the entries in the “count” table have been examined.

Ok Marco (although, in truth, i didn’t understand so well and i didn’t understand what value of t i should write). And to show all the rows of the other tables (sick, healthy, sick count, healthy count) what i have to do ? Thanks.

Ok… these seem to be fairly basic questions, not really related to CUDA … but anyhow:

I should say that this is not a “good program”: It is just a small example, in order to load the stuff from the input file, and show how the computation can be done with CUDA. You could/should spend more time for a better engineering, a better class design (and documentation) and more flexible implementations.

However, there ist a variable
int printedRows = 5;
which says that only the first 5 rows of the tables should be printed - just as a “debug output”, and to avoid filling the console with thousands of lines. You could set
int printedRows = table.getNumRows();
in order to print all rows.

The value of ‘t’ (which should probably renamed to ‘numTasks’ or so…) is computed in the loop

int t = 0;
for (int r=0; r<handledRows; r++)
{
    for (int c0=0; c0<handledCols; c0++)
    {
..
        if (h0 != 0)
        {
            for (int c1=0; c1<handledCols; c1++)
            {
..
                if (s1 != 0)
                {
...
                    t++; // <------------- Here!
                }
            }
        }
    }
}

There it is going through the healthyCount and sickCount-Table, and when the entries of these tables are not ‘0’, then it stores the entries (h0,h1,s0,s1) as one “task”, for which the twoTailedP should be computed. The variable ‘t’ is used for counting the number of tasks. (It is not clear at the beginning how many tasks there will be).

Finally, the tasks are passed to the Java- or CUDA implementation, and for each task (h0,h1,s0,s1) the TwoTailedP is computed, and stored in the ‘results’ array.

Note that there at the moment is a variable

artificiallyIncreaseSize = true;

which is set to ‘true’ and increases the number of tasks artificially (as a “benchmark”). You should set this back to

artificiallyIncreaseSize = false;

to compute only the tasks that have been read from the input file!

Hi Marco. Thanks for the reply. Now i should make some little changes:

  1. Since not always the input file has 28 columns, i should make sure that the program works anyway: how can i do that ? It is possible to “divide” the input file into two parts: for example the first part are the sicks subjects and the second part are the healthy subjects ?

  2. I should add in each table shown on screen, the name of each column and of each row;

  3. I should show, for each probe set id, the little 2x2 matrix (with the name of each column and of each row) instead of:


For  13  13  13  13 : Java : 1,000000    CUDA : 1,000000
For  13   0  13   1 : Java : 0,999997    CUDA : 0,999997
For   1  13   0  13 : Java : 0,999997    CUDA : 0,999997
For   1   0   0   1 : Java : 1,000000    CUDA : 1,000000
For  14  14  14  14 : Java : 1,000002    CUDA : 1,000002
For   2   2   2   2 : Java : 1,000000    CUDA : 1,000000
...

and show only one time the p-value for each little 2x2 matrix (instead of Java: … and CUDA: … just P-value: … since it is the same);

  1. If it is possible, i would like to move the output:

Java Duration ... ms
CUDA Duration ... ms

at the end of all, so that it is more visible.

I’ll try to do it, but please, if it is possible, please help me. Thanks.

  1. That depends on who defines which columns are the “sick” ones and which are the “healthy” ones. In the original Excel-File, this information was taken from the color of the cell, but this information is not available in the CSV file. If you want to, you can return to using the Excel file format. You ““only”” have to change the lines
SimpleTableData sickTable = SimpleTableData.create(table, sickColumns);        
SimpleTableData healthyTable = SimpleTableData.create(table, healthyColumns);   

to something like

SimpleTableData sickTable = createTheTableWithAllSickEntriesMaybeByReading("thisFile.xml");
SimpleTableData healthyTable = createTheTableWithAllHealthyEntriesMaybeByReading("thisFile.xml");

and implement the methods for creating these tables accordingly.

Concerning the other points: Here is an updated main file, but you REALLY should do what is necessary to be able to do things like this on your own! (The problem ist: These things are trivial compared to changing the input from CSV to XML and automatically detect the healthy/sick entries, so I assume that you won’t be able to do this either… -_- )

package fisher;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class JCudaFisherTestMain
{
    private static Map<String, Integer> valueToIndex;
    private static Map<Integer, String> indexToValue;
    
    private static void initMapping()
    {
        valueToIndex = new LinkedHashMap<String, Integer>();
        valueToIndex.put("A/A",  0);
        valueToIndex.put("A/C",  1);
        valueToIndex.put("A/G",  2);
        valueToIndex.put("A/T",  3);
        valueToIndex.put("C/A",  4);
        valueToIndex.put("C/C",  5);
        valueToIndex.put("C/G",  6);
        valueToIndex.put("C/T",  7);
        valueToIndex.put("G/A",  8);
        valueToIndex.put("G/C",  9);
        valueToIndex.put("G/G", 10);
        valueToIndex.put("G/T", 11);
        valueToIndex.put("T/A", 12);
        valueToIndex.put("T/C", 13);
        valueToIndex.put("T/G", 14);
        valueToIndex.put("T/T", 15);
        valueToIndex.put("NoCall", 16);
        valueToIndex.put("-/-", 17);
        valueToIndex.put("-/A", 18);
        valueToIndex.put("-/C", 19);
        valueToIndex.put("-/G", 20);
        valueToIndex.put("-/T", 21);
        valueToIndex.put("A/-", 22);
        valueToIndex.put("C/-", 23);
        valueToIndex.put("G/-", 24);
        valueToIndex.put("T/-", 25);
        indexToValue = reverse(valueToIndex);
    }
    

    
    public static void main(String[] args) throws Exception
    {
        initMapping();
        
        SimpleTableData table = SimpleTableData.read("FirstTable.csv");
        List<Integer> sickColumns = Arrays.asList(
            2, 3, 13, 14, 15, 16, 17, 18,
            19, 20, 21, 22, 25, 27
        );
        Set<Integer> set = new LinkedHashSet<Integer>();
        for (int i=1; i<table.getNumCols(); i++)
        {
            set.add(i);
        }
        set.removeAll(sickColumns);
        List<Integer> healthyColumns = new ArrayList<Integer>(set);

        SimpleTableData sickTable = SimpleTableData.create(table, sickColumns);        
        SimpleTableData healthyTable = SimpleTableData.create(table, healthyColumns);        

        int printedRows = table.getNumRows();
        
        System.out.println("Sick table");
        System.out.println(sickTable.toString(printedRows));

        System.out.println("Healthy table");
        System.out.println(healthyTable.toString(printedRows));
        
        int sickCount[] = createCountMatrix(sickTable);
        int healthyCount[] = createCountMatrix(healthyTable);
        
        int numRows = table.getNumRows();
        int numCols = valueToIndex.size();
        
        int handledRows = numRows;
        int handledCols = numCols;
        
        //System.out.println("Start of sick count table");
        //System.out.println(toString2D(sickCount, numCols, printedRows));

        //System.out.println("Start of healthy count table");
        //System.out.println(toString2D(healthyCount, numCols, printedRows));
        
        System.out.println("Sick count table");
        printCountTable(sickCount, table);

        System.out.println("Healthy count table");
        printCountTable(healthyCount, table);
        
     
        int tasks[] = new int[4];
        int numTasks = 0;
        for (int r=0; r<handledRows; r++)
        {
            for (int c0=0; c0<handledCols; c0++)
            {
              int index0 = c0+r*numCols;
              int h0 = healthyCount[index0];
              if (h0 != 0)
              {
                  for (int c1=0; c1<handledCols; c1++)
                  {
                      int index1 = c1+r*numCols;
                      int s1 = sickCount[index1];
                      if (s1 != 0)
                      {
                          int h1 = healthyCount[index1];
                          int s0 = sickCount[index0];
                          
                          tasks[numTasks*4+0] = h0;
                          tasks[numTasks*4+1] = h1;
                          tasks[numTasks*4+2] = s0;
                          tasks[numTasks*4+3] = s1;
                          
                          boolean printTasks = false;
                          //printTasks = true;
                          if (printTasks)
                          {
                              System.out.println("Storing task:");
                              print(tasks, numTasks, c0, c1);
                          }
                          
                          numTasks++;

                          if (numTasks*4+0 >= tasks.length)
                          {
                              tasks = Arrays.copyOf(tasks, tasks.length*2);
                          }
                      }
                  }
              }
            }
        }

        long before = 0;
        long after = 0;
        
        
        boolean artificiallyIncreaseSize = false;
        //artificiallyIncreaseSize = true;
        if (artificiallyIncreaseSize)
        {
            int n = 100;
            int moreTasks[] = new int[numTasks*n*4];
            for (int i=0; i<n; i++)
            {
                System.arraycopy(tasks, 0, moreTasks, i*numTasks*4, numTasks*4);
            }
            numTasks *= n;
            tasks = moreTasks;
        }
        
        FisherExactTestCore coreJava = new FisherExactTestCoreJava(1000000);
        float resultsJava[] = new float[numTasks];
        before = System.nanoTime();
        coreJava.computeTwoTailedPs(tasks, numTasks, resultsJava);
        after = System.nanoTime();
        double javaDurationMS = (after-before)/1e6;
        
        FisherExactTestCore coreCuda = new FisherExactTestCoreJCuda(1000000);
        float resultsCuda[] = new float[numTasks];
        before = System.nanoTime();
        coreCuda.computeTwoTailedPs(tasks, numTasks, resultsCuda);
        after = System.nanoTime();
        double cudaDurationMS = (after-before)/1e6;
        coreCuda.shutdown();
        
        for (int i=0; i<numTasks; i++)
        {
            int h0 = tasks[i*4+0];
            int h1 = tasks[i*4+1];
            int s0 = tasks[i*4+2];
            int s1 = tasks[i*4+3];
            float resultCuda = resultsCuda**;
            System.out.printf("For %3d %3d %3d %3d : P-value: %f
", h0, h1, s0, s1, resultCuda);
        }

        System.out.println("Java Duration "+javaDurationMS+" ms");
        System.out.println("CUDA Duration "+cudaDurationMS+" ms");

    }
    
    
    private static void printCountTable(int countTable[], SimpleTableData inputTable)
    {
        System.out.println("Count table:");
        StringBuilder sb = new StringBuilder();
        sb.append(String.format("%10s", ""));
        for (int c=0; c<indexToValue.size(); c++)
        {
            sb.append(String.format("%8s", indexToValue.get(c)));
        }
        sb.append("
");
        
        for (int r=0; r<inputTable.getNumRows(); r++)
        {
            String s = String.format("%10s", inputTable.getRow(r).get(0));
            sb.append(s);
            for (int c=0; c<indexToValue.size(); c++)
            {
                int index = c+r*indexToValue.size();
                sb.append(String.format("%8s", countTable[index]));
            }
            sb.append("
");
        }
        System.out.println(sb.toString());
    }
    
    private static void print(int tasks[], int index, int c0, int c1)
    {
        int h0 = tasks[index*4+0];
        int h1 = tasks[index*4+1];
        int s0 = tasks[index*4+2];
        int s1 = tasks[index*4+3];
        System.out.printf("%8s %3s %3s
", "", "H", "S");
        System.out.printf("%8s %3s %3s
", indexToValue.get(c0), String.valueOf(h0), String.valueOf(s0));
        System.out.printf("%8s %3s %3s  ", indexToValue.get(c1), String.valueOf(h1), String.valueOf(s1));        
        System.out.printf("
");        
        System.out.printf("
");        
        
    }
    private static <K, V> Map<V, K> reverse(Map<K, V> input)
    {
        Map<V, K> result = new LinkedHashMap<V, K>();
        for (Entry<K, V> entry : input.entrySet())
        {
            result.put(entry.getValue(), entry.getKey());
        }
        return result;
    }


    private static int[] createCountMatrix(TableData tableData)
    {
        int result[] = new int[valueToIndex.size() * tableData.getNumRows()];
        for (int r=0; r<tableData.getNumRows(); r++)
        {
            for (int c=0; c<tableData.getNumCols(); c++)
            {
                String value = tableData.get(r, c);
                Integer index = valueToIndex.get(value);
                if (index != null)
                {
                    int arrayIndex = r * valueToIndex.size() + index;
                    result[arrayIndex]++;
                }
            }
        }
        return result;
    }
    
    public static String toString2D(int a[], int columns, int maxRows)
    {
        StringBuilder sb = new StringBuilder();
        int row = 0;
        for (int i=0; i<a.length; i++)
        {
            if (i>0 && i % columns == 0)
            {
                sb.append("
");
                row++;
                if (maxRows > 0 && row >= maxRows)
                {
                    sb.append("...
");
                    break;
                }
            }
            sb.append(String.format("%4s ", String.valueOf(a**)));
        }
        return sb.toString();
    }
    
}

Thanks Marco. I’m too much stupid to do something like that, but i’ll try to return to the excel file format and to implement the methods to create the proper table.
If it is possible i just would like to show the probe set id, for example, like this:


For the probe AM_10001:

               Healthy Sick
       C/C       3       0
       C/C       0       4
      
       P-value:  ...

For the probe AM_10002:
     
               Healthy Sick                       Healthy  Sick
       G/G        3      0                  G/G       3        0 
       A/A        0      1                  C/T       0        2
  
       P-value:  ...                        P-value:  ...

For the probe AM_10003:

               Healthy Sick                       Healthy Sick                   Healthy Sick
       C/C        1      3                  C/C       1       3              C/C      1       3
       C/C        1      3                  G/G       0       5              T/T      7       1
     
       P-value:  ...                        P-value:  ...                    P-value:  ...

               Healthy Sick                       Healthy Sick                   Healthy Sick
       C/T        8      0                  C/T        8      0              C/T      8       0
       C/C        1      3                  G/G        0      5              T/T      7       1

       P-value:  ...                        P-value:  ...                    P-value:  ...
             
               Healthy Sick                       Healthy Sick                   Healthy Sick
       T/T        7      1                  T/T       7       1              T/T      7       1
       C/C        1      3                  G/G       0       5              T/T      7       1

       P-value:  ...                        P-value:  ...                    P-value:  ...

If is not possible at least add the probe set id between For and the first value like this:


For AM_10001  13  13  13  13  P-value:  1,000000
For AM_10001  13  0  13  1  P-value:  0,999997
For AM_10001  1  13  0  13  P-value:  0,999997
For AM_10001  1  0  0  1  P-value:  1,000000
For AM_10002  14  14  14  14  P-value:  1,000002
...

Thanks anyway Marco and i wish you to have a nice day.

Send me a reminder next week, then I’ll see what I can do.

Ok Marco. Thanks.

I have integrated a little bit more info in the output. But again, this is just a hack. This program was NEVER intended to become an application that can be extended in any way. It as ONLY intended to show how a CUDA kernel can be used to replace the core of the computation. And I have shown how the computation can (in its simplest form) be done with CUDA. But everything else is up to you.

You should really, really think about an appropriate class structure for what you are going to achieve.

package fisher;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class JCudaFisherTestMain
{
    private static Map<String, Integer> valueToIndex;
    private static Map<Integer, String> indexToValue;
    
    private static void initMapping()
    {
        valueToIndex = new LinkedHashMap<String, Integer>();
        valueToIndex.put("A/A",  0);
        valueToIndex.put("A/C",  1);
        valueToIndex.put("A/G",  2);
        valueToIndex.put("A/T",  3);
        valueToIndex.put("C/A",  4);
        valueToIndex.put("C/C",  5);
        valueToIndex.put("C/G",  6);
        valueToIndex.put("C/T",  7);
        valueToIndex.put("G/A",  8);
        valueToIndex.put("G/C",  9);
        valueToIndex.put("G/G", 10);
        valueToIndex.put("G/T", 11);
        valueToIndex.put("T/A", 12);
        valueToIndex.put("T/C", 13);
        valueToIndex.put("T/G", 14);
        valueToIndex.put("T/T", 15);
        valueToIndex.put("NoCall", 16);
        valueToIndex.put("-/-", 17);
        valueToIndex.put("-/A", 18);
        valueToIndex.put("-/C", 19);
        valueToIndex.put("-/G", 20);
        valueToIndex.put("-/T", 21);
        valueToIndex.put("A/-", 22);
        valueToIndex.put("C/-", 23);
        valueToIndex.put("G/-", 24);
        valueToIndex.put("T/-", 25);
        indexToValue = reverse(valueToIndex);
    }
    

    
    public static void main(String[] args) throws Exception
    {
        initMapping();
        
        SimpleTableData table = SimpleTableData.read("FirstTable.csv");
        List<Integer> sickColumns = Arrays.asList(
            2, 3, 13, 14, 15, 16, 17, 18,
            19, 20, 21, 22, 25, 27
        );
        Set<Integer> set = new LinkedHashSet<Integer>();
        for (int i=1; i<table.getNumCols(); i++)
        {
            set.add(i);
        }
        set.removeAll(sickColumns);
        List<Integer> healthyColumns = new ArrayList<Integer>(set);

        SimpleTableData sickTable = SimpleTableData.create(table, sickColumns);        
        SimpleTableData healthyTable = SimpleTableData.create(table, healthyColumns);        

        int printedRows = table.getNumRows();
        
        System.out.println("Sick table");
        System.out.println(sickTable.toString(printedRows));

        System.out.println("Healthy table");
        System.out.println(healthyTable.toString(printedRows));
        
        int sickCount[] = createCountMatrix(sickTable);
        int healthyCount[] = createCountMatrix(healthyTable);
        
        int numRows = table.getNumRows();
        int numCols = valueToIndex.size();
        
        int handledRows = numRows;
        int handledCols = numCols;
        
        //System.out.println("Start of sick count table");
        //System.out.println(toString2D(sickCount, numCols, printedRows));

        //System.out.println("Start of healthy count table");
        //System.out.println(toString2D(healthyCount, numCols, printedRows));
        
        System.out.println("Sick count table");
        printCountTable(sickCount, table);

        System.out.println("Healthy count table");
        printCountTable(healthyCount, table);
        
        int taskRows[] = new int[1];
        int taskCols[] = new int[2];
        int tasks[] = new int[4];
        int numTasks = 0;
        for (int r=0; r<handledRows; r++)
        {
            for (int c0=0; c0<handledCols; c0++)
            {
              int index0 = c0+r*numCols;
              int h0 = healthyCount[index0];
              if (h0 != 0)
              {
                  for (int c1=0; c1<handledCols; c1++)
                  {
                      int index1 = c1+r*numCols;
                      int s1 = sickCount[index1];
                      if (s1 != 0)
                      {
                          int h1 = healthyCount[index1];
                          int s0 = sickCount[index0];
                          
                          tasks[numTasks*4+0] = h0;
                          tasks[numTasks*4+1] = h1;
                          tasks[numTasks*4+2] = s0;
                          tasks[numTasks*4+3] = s1;
                          taskRows[numTasks] = r;
                          taskCols[numTasks*2+0] = c0;
                          taskCols[numTasks*2+1] = c1;
                          
                          boolean printTasks = false;
                          //printTasks = true;
                          if (printTasks)
                          {
                              System.out.println("Storing task:");
                              print(tasks, numTasks, c0, c1);
                          }
                          
                          numTasks++;

                          if (numTasks*4+0 >= tasks.length)
                          {
                              tasks = Arrays.copyOf(tasks, tasks.length*2);
                              taskRows = Arrays.copyOf(taskRows, taskRows.length*2);
                              taskCols = Arrays.copyOf(taskCols, taskCols.length*2);
                          }
                      }
                  }
              }
            }
        }

        long before = 0;
        long after = 0;
        
        
        boolean artificiallyIncreaseSize = false;
        //artificiallyIncreaseSize = true;
        if (artificiallyIncreaseSize)
        {
            int n = 100;
            int moreTasks[] = new int[numTasks*n*4];
            for (int i=0; i<n; i++)
            {
                System.arraycopy(tasks, 0, moreTasks, i*numTasks*4, numTasks*4);
            }
            numTasks *= n;
            tasks = moreTasks;
        }
        
        FisherExactTestCore coreJava = new FisherExactTestCoreJava(1000000);
        float resultsJava[] = new float[numTasks];
        before = System.nanoTime();
        coreJava.computeTwoTailedPs(tasks, numTasks, resultsJava);
        after = System.nanoTime();
        double javaDurationMS = (after-before)/1e6;
        
        FisherExactTestCore coreCuda = new FisherExactTestCoreJCuda(1000000);
        float resultsCuda[] = new float[numTasks];
        before = System.nanoTime();
        coreCuda.computeTwoTailedPs(tasks, numTasks, resultsCuda);
        after = System.nanoTime();
        double cudaDurationMS = (after-before)/1e6;
        coreCuda.shutdown();
        
        for (int i=0; i<numTasks; i++)
        {
            int h0 = tasks[i*4+0];
            int h1 = tasks[i*4+1];
            int s0 = tasks[i*4+2];
            int s1 = tasks[i*4+3];
            float resultCuda = resultsCuda**;

            int row = taskRows**;
            String rowId = table.get(row, 0);
            int col0 = taskCols[i*2+0];
            int col1 = taskCols[i*2+1];
            String colId0 = indexToValue.get(col0);
            String colId1 = indexToValue.get(col1);
            String description = String.format("%-10s (%-7s,%-7s)", rowId, colId0, colId1);
            String results = String.format("%3d %3d %3d %3d : P-value: %f
", h0, h1, s0, s1, resultCuda);
            System.out.println(description+" : "+results);
        }

        System.out.println("Java Duration "+javaDurationMS+" ms");
        System.out.println("CUDA Duration "+cudaDurationMS+" ms");

    }
    
    
    private static void printCountTable(int countTable[], SimpleTableData inputTable)
    {
        System.out.println("Count table:");
        StringBuilder sb = new StringBuilder();
        sb.append(String.format("%10s", ""));
        for (int c=0; c<indexToValue.size(); c++)
        {
            sb.append(String.format("%8s", indexToValue.get(c)));
        }
        sb.append("
");
        
        for (int r=0; r<inputTable.getNumRows(); r++)
        {
            String s = String.format("%10s", inputTable.getRow(r).get(0));
            sb.append(s);
            for (int c=0; c<indexToValue.size(); c++)
            {
                int index = c+r*indexToValue.size();
                sb.append(String.format("%8s", countTable[index]));
            }
            sb.append("
");
        }
        System.out.println(sb.toString());
    }
    
    private static void print(int tasks[], int index, int c0, int c1)
    {
        int h0 = tasks[index*4+0];
        int h1 = tasks[index*4+1];
        int s0 = tasks[index*4+2];
        int s1 = tasks[index*4+3];
        System.out.printf("%8s %3s %3s
", "", "H", "S");
        System.out.printf("%8s %3s %3s
", indexToValue.get(c0), String.valueOf(h0), String.valueOf(s0));
        System.out.printf("%8s %3s %3s  ", indexToValue.get(c1), String.valueOf(h1), String.valueOf(s1));        
        System.out.printf("
");        
        System.out.printf("
");        
        
    }
    private static <K, V> Map<V, K> reverse(Map<K, V> input)
    {
        Map<V, K> result = new LinkedHashMap<V, K>();
        for (Entry<K, V> entry : input.entrySet())
        {
            result.put(entry.getValue(), entry.getKey());
        }
        return result;
    }


    private static int[] createCountMatrix(TableData tableData)
    {
        int result[] = new int[valueToIndex.size() * tableData.getNumRows()];
        for (int r=0; r<tableData.getNumRows(); r++)
        {
            for (int c=0; c<tableData.getNumCols(); c++)
            {
                String value = tableData.get(r, c);
                Integer index = valueToIndex.get(value);
                if (index != null)
                {
                    int arrayIndex = r * valueToIndex.size() + index;
                    result[arrayIndex]++;
                }
            }
        }
        return result;
    }
    
    public static String toString2D(int a[], int columns, int maxRows)
    {
        StringBuilder sb = new StringBuilder();
        int row = 0;
        for (int i=0; i<a.length; i++)
        {
            if (i>0 && i % columns == 0)
            {
                sb.append("
");
                row++;
                if (maxRows > 0 && row >= maxRows)
                {
                    sb.append("...
");
                    break;
                }
            }
            sb.append(String.format("%4s ", String.valueOf(a**)));
        }
        return sb.toString();
    }
    
}

Hi Marco. The purpose of this program is just to show the potential of CUDA, nothing else: there will not be a program. Now remains the problem that not always the input file has about 30 columns: i’m looking for a possible solution, but if i’ll have some problem (i believe there will be), i’ll ask here for your possible help. Thank you very much.

Hi Marco. I’ve implemented this that just read (and print) the .xls file (named XLS_file.xls) with the help of this API:

import java.io.File;
import java.io.IOException;

import jxl.Cell;
import jxl.DateCell;
import jxl.LabelCell;
import jxl.NumberCell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;

public class ReadExcel {

    public static void main(String[] args) {

        Cell subject;
        String subjectCell = "";
        LabelCell lc;

        try {
            //Open the excel file to read
            Workbook workbook = Workbook.getWorkbook(new File("XLS_file.xls"));
            //Select the sheet with which i have to work (the first sheet has index 0)
            Sheet sheet = workbook.getSheet(0);

            for (int i = 0; i < sheet.getRows(); i++) {
                for (int j = 0; j < sheet.getColumns(); j++) {
                    subject = sheet.getCell(j, i);
                    lc = (LabelCell) subject;
                    subjectCell = lc.getString();
                    System.out.print(subjectCell + " ");
                }
                System.out.println();
            }
            
            //Close excel and free memory
            workbook.close();

        } catch (BiffException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Now how can i do to split the file in 2 parts: the first part are sick and the second are the healthy ? I’d like to add also in this firsts 2 tables of sick and healthy, the column with the probe set id, how can i do ? Thanks in advance.