9.5 Example

A complete example can be found in projects/matrix_multiply/CLA_Matrix in CVS. What follows are some of the more important files from that example.

In the users .ci file:

mainmodule matTest {
  extern module CLA_Matrix; // make sure to include, or get Charm++ errors
  ...
  readonly CProxy_tester dataProxyA;
  readonly CProxy_tester dataProxyB;
  readonly CProxy_tester dataProxyC;
  ...
  mainchare Main {
    ...
    entry void chunk_inited(); // callback to know library is ready
  };
  ...
  array [2D] tester{
    ...
    entry void multiply(double alpha, double beta); // start multiplication
  };
};

In the main function:

...
/* create interface objects, data proxies*/
CLA_Matrix_interface matA, matB, matC;

dataProxyA = CProxy_tester::ckNew();
dataProxyB = CProxy_tester::ckNew();
dataProxyC = CProxy_tester::ckNew();

/* make multicast manager, callback */
CkGroupID gid = CProxy_CkMulticastMgr::ckNew();
CkCallback *cb = new CkCallback(CkIndex_Main::chunk_inited(), mainProxy);

/* size and stride variable determined earlier, ready to init library */
make_multiplier(&matA, &matB, &matC, dataProxyA, dataProxyB, dataProxyC, M, K,
  N, m, k, n, M_stride, K_stride, N_stride, *cb, *cb, *cb, gid, MM_ALG_2D);

...
/* create tester objects */
for(i = ...)
  for(j = ...)
    dataProxyA(i, j).insert(...);
dataProxyA.doneInserting();
...

When the library is ready, tell the tester (user) objects to multiply:

void chunk_inited(){
  /* make sure all three proxies are ready */
  if(++msg_received != 3)
    return;
  dataProxyA.multiply(1, 0);
  dataProxyB.multiply(1, 0);
  dataProxyC.multiply(1, 0);
}

The user's objects start the multiplication:

void tester::multiply(double alpha, double beta){
  /* "matrix" is the CLA_Matrix_interface object created in main. */
  /* pass "this" as the user_data argument so that we can dereference it
   * in done_cb below. */
  matrix.multiply(alpha, beta, data, tester::done_cb, (void*) this,
   thisIndex.x, thisIndex.y);
}

The C tester object will be notified when the multiplication has completed.

class tester {
  ...
  static void done_cb(void *obj){
      ((tester*) obj)->round_done();
  }
  void round_done(){
    CkPrintf("[%d %d] has its chunk of C ready.\n", thisIndex.x, thisIndex.y);
    // continue with user's code, doing something useful
    ...
  }
  ...
};



February 13, 2012
Charm Homepage