コード例 #1
0
int main(int argc, char* argv[])
{
  pami_result_t result = PAMI_ERROR;

  if (Kernel_GetRank()==0)
    print_meminfo(stdout, "before PAMI_Client_create");

  /* initialize the client */
  char * clientname = "";
  pami_client_t client;
  result = PAMI_Client_create( clientname, &client, NULL, 0 );
  TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Client_create");

  if (Kernel_GetRank()==0)
    print_meminfo(stdout, "after PAMI_Client_create");

  /* query properties of the client */
  pami_configuration_t config;
  size_t num_contexts;

  config.name = PAMI_CLIENT_TASK_ID;
  result = PAMI_Client_query( client, &config, 1);
  TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Client_query");
  world_rank = config.value.intval;

  config.name = PAMI_CLIENT_NUM_TASKS;
  result = PAMI_Client_query( client, &config, 1);
  TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Client_query");
  world_size = config.value.intval;

  if ( world_rank == 0 ) 
  {
    printf("starting test on %ld ranks \n", world_size);
    fflush(stdout);
  }

  config.name = PAMI_CLIENT_PROCESSOR_NAME;
  result = PAMI_Client_query( client, &config, 1);
  assert(result == PAMI_SUCCESS);
  //printf("rank %ld is processor %s \n", world_rank, config.value.chararray);
  //fflush(stdout);

  config.name = PAMI_CLIENT_NUM_CONTEXTS;
  result = PAMI_Client_query( client, &config, 1);
  TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Client_query");
  num_contexts = config.value.intval;

  /* initialize the contexts */
  pami_context_t * contexts = NULL;
  contexts = (pami_context_t *) malloc( num_contexts * sizeof(pami_context_t) ); assert(contexts!=NULL);

  if (Kernel_GetRank()==0)
    fprintf(stdout, "num_contexts = %ld \n", (long)num_contexts);

  result = PAMI_Context_createv( client, &config, 0, contexts, num_contexts );
  TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Context_createv");

  if (Kernel_GetRank()==0)
    print_meminfo(stdout, "after PAMI_Context_createv");

  /* setup the world geometry */
  pami_geometry_t world_geometry;
  pami_xfer_type_t barrier_xfer = PAMI_XFER_BARRIER;
  size_t num_alg[2];
  pami_algorithm_t * safe_barrier_algs = NULL;
  pami_metadata_t  * safe_barrier_meta = NULL;
  pami_algorithm_t * fast_barrier_algs = NULL;
  pami_metadata_t  * fast_barrier_meta = NULL;

  result = PAMI_Geometry_world( client, &world_geometry );
  TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Geometry_world");

  if (Kernel_GetRank()==0)
    print_meminfo(stdout, "after PAMI_Geometry_world");

  result = PAMI_Geometry_algorithms_num( world_geometry, barrier_xfer, num_alg );
  TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Geometry_algorithms_num");
  if ( world_rank == 0 ) printf("number of barrier algorithms = {%ld,%ld} \n", num_alg[0], num_alg[1] );

  if (Kernel_GetRank()==0)
    print_meminfo(stdout, "after PAMI_Geometry_algorithms_num");

  safe_barrier_algs = (pami_algorithm_t *) malloc( num_alg[0] * sizeof(pami_algorithm_t) ); assert(safe_barrier_algs!=NULL);
  safe_barrier_meta = (pami_metadata_t  *) malloc( num_alg[0] * sizeof(pami_metadata_t)  ); assert(safe_barrier_meta!=NULL);
  fast_barrier_algs = (pami_algorithm_t *) malloc( num_alg[1] * sizeof(pami_algorithm_t) ); assert(fast_barrier_algs!=NULL);
  fast_barrier_meta = (pami_metadata_t  *) malloc( num_alg[1] * sizeof(pami_metadata_t)  ); assert(fast_barrier_meta!=NULL);
  result = PAMI_Geometry_algorithms_query( world_geometry, barrier_xfer,
                                           safe_barrier_algs, safe_barrier_meta, num_alg[0],
                                           fast_barrier_algs, fast_barrier_meta, num_alg[1] );
  TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Geometry_algorithms_query");

  if (Kernel_GetRank()==0)
    print_meminfo(stdout, "after PAMI_Geometry_algorithms_query");

  /* perform a barrier */
  size_t b;
  pami_xfer_t barrier;
  volatile int active = 0;

  for ( b = 0 ; b < num_alg[0] ; b++ )
  {
      barrier.cb_done   = cb_done;
      barrier.cookie    = (void*) &active;
      barrier.algorithm = safe_barrier_algs[b];

      uint64_t t0 = GetTimeBase();
      active = 1;
      result = PAMI_Collective( contexts[0], &barrier );
      TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Collective - barrier");
      while (active)
        result = PAMI_Context_advance( contexts[0], 1 );
      TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Context_advance - barrier");
      uint64_t t1 = GetTimeBase();

      if ( world_rank == 0 ) printf("safe barrier algorithm %ld (%s) - took %llu cycles \n", b, safe_barrier_meta[b].name, (long long unsigned int)t1-t0 );
      fflush(stdout);
  }
  for ( b = 0 ; b < num_alg[1] ; b++ )
  {
      barrier.cb_done   = cb_done;
      barrier.cookie    = (void*) &active;
      barrier.algorithm = fast_barrier_algs[b];

      uint64_t t0 = GetTimeBase();
      active = 1;
      result = PAMI_Collective( contexts[0], &barrier );
      TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Collective - barrier");
      while (active)
        result = PAMI_Context_advance( contexts[0], 1 );
      TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Context_advance - barrier");
      uint64_t t1 = GetTimeBase();

      if ( world_rank == 0 ) printf("fast barrier algorithm %ld (%s) - took %llu cycles \n", b, fast_barrier_meta[b].name, (long long unsigned int)t1-t0 );
      fflush(stdout);
  }

  if (Kernel_GetRank()==0)
    print_meminfo(stdout, "after barrier tests");

  /* finalize the contexts */
  result = PAMI_Context_destroyv( contexts, num_contexts );
  TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Context_destroyv");

  free(contexts);

  if (Kernel_GetRank()==0)
    print_meminfo(stdout, "before PAMI_Client_destroy");

  /* finalize the client */
  result = PAMI_Client_destroy( &client );
  TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Client_destroy");

  if (Kernel_GetRank()==0)
    print_meminfo(stdout, "after PAMI_Client_destroy");

  if ( world_rank == 0 ) 
  {
    printf("end of test \n");
    fflush(stdout);
  }

  return 0;
}
コード例 #2
0
ファイル: mpid_selectcolls.c プロジェクト: dbrowneup/pmap
/* Determine how many of each collective type this communicator supports */
void MPIDI_Comm_coll_query(MPID_Comm *comm)
{
   TRACE_ERR("MPIDI_Comm_coll_query enter\n");
   int rc = 0, i, j;
   size_t num_algorithms[2];
   TRACE_ERR("Getting geometry from comm %p\n", comm);
   pami_geometry_t *geom = comm->mpid.geometry;;
   for(i = 0; i < PAMI_XFER_COUNT; i++)
   {
      if(i == PAMI_XFER_AMBROADCAST || i == PAMI_XFER_AMSCATTER ||
         i == PAMI_XFER_AMGATHER || i == PAMI_XFER_AMREDUCE)
         continue;
      rc = PAMI_Geometry_algorithms_num(geom,
                                        i,
                                        num_algorithms);
      TRACE_ERR("Num algorithms of type %d: %zd %zd\n", i, num_algorithms[0], num_algorithms[1]);
      if(rc != PAMI_SUCCESS)
      {
         fprintf(stderr,"PAMI_Geometry_algorithms_num returned %d for type %d\n", rc, i);
         continue;
      }

      comm->mpid.coll_count[i][0] = 0;
      comm->mpid.coll_count[i][1] = 0;
      if(num_algorithms[0] || num_algorithms[1])
      {
         comm->mpid.coll_algorithm[i][0] = (pami_algorithm_t *)
               MPIU_Malloc(sizeof(pami_algorithm_t) * num_algorithms[0]);
         comm->mpid.coll_metadata[i][0] = (pami_metadata_t *)
               MPIU_Malloc(sizeof(pami_metadata_t) * num_algorithms[0]);
         comm->mpid.coll_algorithm[i][1] = (pami_algorithm_t *)
               MPIU_Malloc(sizeof(pami_algorithm_t) * num_algorithms[1]);
         comm->mpid.coll_metadata[i][1] = (pami_metadata_t *)
               MPIU_Malloc(sizeof(pami_metadata_t) * num_algorithms[1]);
         comm->mpid.coll_count[i][0] = num_algorithms[0];
         comm->mpid.coll_count[i][1] = num_algorithms[1];

         /* Despite the bad name, this looks at algorithms associated with
          * the geometry, NOT inherent physical properties of the geometry*/

         /* BES TODO I am assuming all contexts have the same algorithms. Probably
          * need to investigate that assumption
          */
         rc = PAMI_Geometry_algorithms_query(geom,
                                             i,
                                             comm->mpid.coll_algorithm[i][0],
                                             comm->mpid.coll_metadata[i][0],
                                             num_algorithms[0],
                                             comm->mpid.coll_algorithm[i][1],
                                             comm->mpid.coll_metadata[i][1],
                                             num_algorithms[1]);
         if(rc != PAMI_SUCCESS)
         {
            fprintf(stderr,"PAMI_Geometry_algorithms_query returned %d for type %d\n", rc, i);
            continue;
         }

         if(MPIDI_Process.verbose >= MPIDI_VERBOSE_DETAILS_0 && comm->rank == 0)
         {
            for(j = 0; j < num_algorithms[0]; j++)
               fprintf(stderr,"comm[%p] coll type %d (%s), algorithm %d 0: %s\n", comm, i, MPIDI_Coll_type_name(i), j, comm->mpid.coll_metadata[i][0][j].name);
            for(j = 0; j < num_algorithms[1]; j++)
               fprintf(stderr,"comm[%p] coll type %d (%s), algorithm %d 1: %s\n", comm, i, MPIDI_Coll_type_name(i), j, comm->mpid.coll_metadata[i][1][j].name);
            if(i == PAMI_XFER_ALLGATHERV_INT || i == PAMI_XFER_ALLGATHER)
            {
               fprintf(stderr,"comm[%p] coll type %d (%s), \"glue\" algorithm: GLUE_ALLREDUCE\n", comm, i, MPIDI_Coll_type_name(i));
               fprintf(stderr,"comm[%p] coll type %d (%s), \"glue\" algorithm: GLUE_BCAST\n", comm, i, MPIDI_Coll_type_name(i));
               fprintf(stderr,"comm[%p] coll type %d (%s), \"glue\" algorithm: GLUE_ALLTOALL\n", comm, i, MPIDI_Coll_type_name(i));
            }
            if(i == PAMI_XFER_SCATTERV_INT)
            {
               fprintf(stderr,"comm[%p] coll type %d (%s), \"glue\" algorithm: GLUE_BCAST\n", comm, i, MPIDI_Coll_type_name(i));
               fprintf(stderr,"comm[%p] coll type %d (%s), \"glue\" algorithm: GLUE_ALLTOALLV\n", comm, i, MPIDI_Coll_type_name(i));
            }
            if(i == PAMI_XFER_SCATTER)
            {
               fprintf(stderr,"comm[%p] coll type %d (%s), \"glue\" algorithm: GLUE_BCAST\n", comm, i, MPIDI_Coll_type_name(i));
            }
         }
      }
   }
   /* Determine if we have protocols for these maybe, rather than just setting them? */
   comm->coll_fns->Barrier      = MPIDO_Barrier;
   comm->coll_fns->Bcast        = MPIDO_Bcast;
   comm->coll_fns->Allreduce    = MPIDO_Allreduce;
   comm->coll_fns->Allgather    = MPIDO_Allgather;
   comm->coll_fns->Allgatherv   = MPIDO_Allgatherv;
   comm->coll_fns->Scatterv     = MPIDO_Scatterv;
   comm->coll_fns->Scatter      = MPIDO_Scatter;
   comm->coll_fns->Gather       = MPIDO_Gather;
   comm->coll_fns->Alltoallv    = MPIDO_Alltoallv;
   comm->coll_fns->Alltoall     = MPIDO_Alltoall;
   comm->coll_fns->Gatherv      = MPIDO_Gatherv;
   comm->coll_fns->Reduce       = MPIDO_Reduce;
   comm->coll_fns->Scan         = MPIDO_Scan;
   comm->coll_fns->Exscan       = MPIDO_Exscan;

   TRACE_ERR("MPIDI_Comm_coll_query exit\n");
}
コード例 #3
0
ファイル: ListCollectiveOptions.c プロジェクト: sirinath/x10
int main(int argc, char ** argv) {
	pami_client_t client;
	pami_context_t context;
	size_t num_contexts = 1;
	pami_task_t task_id;
	size_t num_tasks;
	pami_geometry_t world_geometry;
	/* Barrier variables */
	size_t num_algorithms[2];
	pami_xfer_type_t barrier_xfer = PAMI_XFER_BARRIER;
	pami_xfer_t barrier;
#if !defined(__bgq__)
	pami_extension_t hfi_extension;
	hfi_remote_update_fn hfi_update;
#endif
	int numAlgorithms = 6;
	pami_xfer_type_t algorithms[] = {PAMI_XFER_BROADCAST, PAMI_XFER_BARRIER,
			PAMI_XFER_SCATTER, PAMI_XFER_ALLTOALL, PAMI_XFER_ALLREDUCE, PAMI_XFER_ALLGATHER};
	const char* algorithmNames[] = {"PAMI_XFER_BROADCAST", "PAMI_XFER_BARRIER",
				"PAMI_XFER_SCATTER", "PAMI_XFER_ALLTOALL", "PAMI_XFER_ALLREDUCE", "PAMI_XFER_ALLGATHER"};

	const char    *name = "X10";
	setenv("MP_MSG_API", name, 1);
	pami_configuration_t config;
	config.name = PAMI_GEOMETRY_OPTIMIZE;
	config.value.intval = 1;

	pami_result_t status = PAMI_Client_create(name, &client, &config, 1);
	if (status != PAMI_SUCCESS)
		error("Unable to initialize PAMI client\n");

	if ((status = PAMI_Context_createv(client, &config, 1, &context, 1)) != PAMI_SUCCESS)
		error("Unable to initialize the PAMI context: %i\n", status);

#if !defined(__bgq__)
	status = PAMI_Extension_open (client, "EXT_hfi_extension", &hfi_extension);
	if (status == PAMI_SUCCESS)
	{
		#ifdef __GNUC__
		__extension__
		#endif
		hfi_update = (hfi_remote_update_fn) PAMI_Extension_symbol(hfi_extension, "hfi_remote_update"); // This may succeed even if HFI is not available
	}
#endif

	status = PAMI_Geometry_world(client, &world_geometry);
		if (status != PAMI_SUCCESS) error("Unable to create the world geometry");

	pami_configuration_t configuration[2];
	configuration[0].name = PAMI_CLIENT_TASK_ID;
	configuration[1].name = PAMI_CLIENT_NUM_TASKS;
	if ((status = PAMI_Client_query(client, configuration, 2)) != PAMI_SUCCESS)
		error("Unable to query the PAMI_CLIENT: %i\n", status);
	int myPlaceId = configuration[0].value.intval;

	if (myPlaceId == 0)
	{
		for (int i = 0; i < numAlgorithms; i++) {
			status = PAMI_Geometry_algorithms_num(world_geometry, algorithms[i], num_algorithms);
			if (status != PAMI_SUCCESS || num_algorithms[0] == 0)
				error("Unable to query the algorithm counts for barrier\n");

			// query what the different algorithms are
			pami_algorithm_t *always_works_alg = (pami_algorithm_t*) alloca(sizeof(pami_algorithm_t)*num_algorithms[0]);
			pami_metadata_t	*always_works_md = (pami_metadata_t*) alloca(sizeof(pami_metadata_t)*num_algorithms[0]);
			pami_algorithm_t *must_query_alg = (pami_algorithm_t*) alloca(sizeof(pami_algorithm_t)*num_algorithms[1]);
			pami_metadata_t	*must_query_md = (pami_metadata_t*) alloca(sizeof(pami_metadata_t)*num_algorithms[1]);
			status = PAMI_Geometry_algorithms_query(world_geometry, algorithms[i], always_works_alg,
					always_works_md, num_algorithms[0], must_query_alg, must_query_md, num_algorithms[1]);
			if (status != PAMI_SUCCESS)
				error("Unable to query the supported algorithm %s for world", algorithmNames[i]);

			// print out
			printf("Collective: %s\n", algorithmNames[i]);
			printf("Always supported: %i algorithms\n", num_algorithms[0]);
			for (int j=0; j<num_algorithms[0]; j++)
				printf("\t%s = %i\n", always_works_md[j].name, j);
			printf("Locally supported: %i algorithms\n", num_algorithms[1]);
			for (int j=0; j<num_algorithms[1]; j++)
				printf("\t%s = %i\n", must_query_md[j].name, num_algorithms[0]+j);
			printf("\n");
		}
	}

#if !defined(__bgq__)
	PAMI_Extension_close (hfi_extension);
#endif

	if ((status = PAMI_Context_destroyv(&context, 1)) != PAMI_SUCCESS)
		fprintf(stderr, "Error closing PAMI context: %i\n", status);
	if ((status = PAMI_Client_destroy(&client)) != PAMI_SUCCESS)
		fprintf(stderr, "Error closing PAMI client: %i\n", status);
	return 0;
}
コード例 #4
0
ファイル: gasnet_coll_pami.c プロジェクト: chapel-lang/chapel
/* Get the default algorithm for a given (geometery, collective) pair.
   This will be the first "always works" algorithm unless user provides an override.
*/
extern void
gasnetc_dflt_coll_alg(pami_geometry_t geom, pami_xfer_type_t op, pami_algorithm_t *alg_p) {
  static int print_once[PAMI_XFER_COUNT]; /* static var must initially be all zeros */
  pami_result_t rc;
  size_t counts[2];
  pami_algorithm_t *algorithms;
  pami_metadata_t *metadata;
  const char *envvar, *envval, *dfltval;
  int alg, fullcount;

  gasneti_assert(op >= 0);
  gasneti_assert(op < PAMI_XFER_COUNT);

  rc = PAMI_Geometry_algorithms_num(geom, op, counts);
  GASNETC_PAMI_CHECK(rc, "calling PAMI_Geometry_algorithms_num()");
  fullcount = counts[0] + counts[1];

  /* Space for algorithms and metadata */
  algorithms = alloca(fullcount * sizeof(pami_algorithm_t));
  metadata   = alloca(fullcount * sizeof(pami_metadata_t));

  rc = PAMI_Geometry_algorithms_query(geom, op,
                                      algorithms, metadata, counts[0],
                                      algorithms+counts[0], metadata+counts[0], counts[1]);
  GASNETC_PAMI_CHECK(rc, "calling PAMI_Geometry_algorithms_query()");

  /* Process environment and defaults: */
  switch(op) { /* please keep alphabetical */
  /* Used for blocking gasnet exchange: */
  case PAMI_XFER_ALLTOALL:
    envvar = "GASNET_PAMI_ALLTOALL_ALG";
  #if GASNETI_ARCH_BGQ
    dfltval = "I0:M2MComposite:MU:MU"; /* Best on BG/Q by a large margin */
  #else
    dfltval = "I0:Ring:"; /* Uniformly 2nd place (out of 3) on PERCS */
  #endif
    break;

  /* Used for blocking gasnet exchange w/ multiple images: */
  case PAMI_XFER_ALLTOALLV_INT:
    envvar = "GASNET_PAMI_ALLTOALLV_INT_ALG";
  #if GASNETI_ARCH_BGQ
    dfltval = "I0:M2MComposite:MU:MU"; /* Best on BG/Q by a large margin */
  #else
    dfltval = "I0:M2MComposite:"; /* Best on PERCS for all but smallest len (where it is close) */
  #endif
    break;

  /* Used for blocking gasnet gatherall and gasnetc_bootstrapExchange(): */
  case PAMI_XFER_ALLGATHER:
    envvar = "GASNET_PAMI_ALLGATHER_ALG";
  #if GASNETI_ARCH_BGQ && 0 /* TODO: split choice based on size */
    dfltval = "I0:RectangleDput:"; /* Uniformly best (or very near) for LARGE case only... */
    /* .. but only available for "rectangular" jobs. */
    alg = gasnetc_find_alg(dfltval, metadata, counts[0]);
    if (alg < counts[0]) break; /* Otherwise fall through */
  #endif
    dfltval = "I0:Binomial:"; /* Uniformly 2nd place (out of 3) on PERCS, uniformly "OK" on BG/Q */
    break;

  /* Used for blocking gasnet gatherall w/ multiple images: */
  case PAMI_XFER_ALLGATHERV_INT:
    envvar = "GASNET_PAMI_ALLGATHERV_INT_ALG";
  #if GASNETI_ARCH_BGQ && 0 /* TODO: split choice based on size */
    dfltval = "I0:RectangleDput:"; /* Uniformly best for small to moderate cases only ... */
    /* .. but only available for "rectangular" jobs. */
    alg = gasnetc_find_alg(dfltval, metadata, counts[0]);
    if (alg < counts[0]) break; /* Otherwise fall through */
  #endif
    dfltval = NULL; /* Only one other option available on systems I've tested -PHH */
    break;

  /* Used for exitcode reduction and "PAMIALLREDUCE" barrier: */
  case PAMI_XFER_ALLREDUCE:
    envvar = "GASNET_PAMI_ALLREDUCE_ALG";
  #if GASNETI_ARCH_BGQ
    dfltval = "I0:Binomial:-:ShortMU"; /* great when available */
    alg = gasnetc_find_alg(dfltval, metadata, fullcount);
    if (alg < fullcount) {
      /* make sure PAMI-allreduce barrier and exitcode reduction will "fit" */
      pami_metadata_t *md = &metadata[alg];
      if ((!md->check_correct.values.rangeminmax  || md->range_lo <= sizeof(int)) &&
          (!md->check_correct.values.rangeminmax  || md->range_hi >= 2*sizeof(uint64_t)) &&
          (!md->check_correct.values.sendminalign || md->send_min_align >= sizeof(char)) &&
          (!md->check_correct.values.recvminalign || md->recv_min_align >= sizeof(char))) {
        break; /* Otherwise fall through */
      }
    }
    dfltval = "I1:ShortAllreduce:"; /* excellent second choice on BG/Q */
    alg = gasnetc_find_alg(dfltval, metadata, fullcount);
    if (alg < fullcount) {
      /* make sure PAMI-allreduce barrier and exitcode reduction will "fit" */
      pami_metadata_t *md = &metadata[alg];
      if ((!md->check_correct.values.rangeminmax  || md->range_lo <= sizeof(int)) &&
          (!md->check_correct.values.rangeminmax  || md->range_hi >= 2*sizeof(uint64_t)) &&
          (!md->check_correct.values.sendminalign || md->send_min_align >= sizeof(char)) &&
          (!md->check_correct.values.recvminalign || md->recv_min_align >= sizeof(char))) {
        break; /* Otherwise fall through */
      }
    }
  #endif
    dfltval = "I0:Binomial:"; /* uniformly "good" on BG/Q and PERCS */
    break;

  /* Used for gasnetc_fast_barrier() and GASNET_BARRIERFLAG_UNNAMED */
  case PAMI_XFER_BARRIER:
    envvar = "GASNET_PAMI_BARRIER_ALG";
  #if GASNETI_ARCH_BGQ
    /* Note: this could be any of
     *     "I0:MultiSync2Device:SHMEM:GI"
     *     "I0:MultiSync:SHMEM:-",
     *     "I0:MultiSync:-:GI",
     * depending on job layout, and may not be available on team != ALL.
     */
    dfltval = "I0:MultiSync";
    alg = gasnetc_find_alg(dfltval, metadata, counts[0]);
    if (alg < counts[0]) break; /* Otherwise fall through */
  #endif
    dfltval = NULL; /* TODO: tune a better default than alg[0]? */
    break;

  /* Used for blocking gasnet broadcast: */
  case PAMI_XFER_BROADCAST:
    envvar = "GASNET_PAMI_BROADCAST_ALG";
  #if GASNETI_ARCH_BGQ
    dfltval = "I0:2-nary:"; /* uniformly "near-best" on BG/Q */
  #else
   #if 0 /* Seen to deadlock when using multiple procs/node */
    dfltval = "I0:4-nary:"; /* uniformly "near-best" on PERSC */
   #else
    dfltval = NULL; /* TODO: tune for better default or wait for bug fix */
   #endif
  #endif
    break;

  /* Used for blocking gasnet gather: */
  case PAMI_XFER_GATHER:
    envvar = "GASNET_PAMI_GATHER_ALG";
    dfltval = NULL; /* TODO: tune for better default */
    break;

  /* Used for blocking gasnet gather w/ multiple images: */
  case PAMI_XFER_GATHERV_INT:
    envvar = "GASNET_PAMI_GATHERV_INT_ALG";
    dfltval = NULL; /* TODO: tune for better default */
    break;

  /* Used for blocking gasnet scatter: */
  case PAMI_XFER_SCATTER:
    envvar = "GASNET_PAMI_SCATTER_ALG";
    dfltval = "I0:Binomial:"; /* uniformly "good" on BG/Q and PERSC */
    break;

  /* Used for blocking gasnet scatter w/ multiple images: */
  case PAMI_XFER_SCATTERV_INT:
    envvar = "GASNET_PAMI_SCATTERV_INT_ALG";
    dfltval = NULL; /* TODO: tune for better default */
    break;

  default:
    gasneti_fatalerror("Unknown 'op' value %d in %s", (int)op, __FUNCTION__);
    envvar = dfltval = NULL; /* for warning suppression only */
  }
  /* Override the defaults above for the single-task case: */
  if (gasneti_nodes == 1) {
    const char *onetask = "I0:OneTask";
    if (gasnetc_find_alg(onetask, metadata, counts[0]) < counts[0]) {
      dfltval = onetask;
    }
  }
  /* Now the user's environment value if any: */
  envval = gasneti_getenv_withdefault(envvar, dfltval);
  alg = 0; /* failsafe */
  if (NULL != envval) {
    while (envval[0] && isspace(envval[0])) ++envval; /* leading whitespace */
    if (!envval[0]) {
      /* empty - treat as zero */
    } else if (0 == strcmp("LIST", envval)) {
      if (!gasneti_mynode && !print_once[(int)op]) {
        int i;
        fprintf(stderr, "Listing available values for environment variable %s:\n", envvar);
        for (i=0; i<fullcount; ++i) {
          fprintf(stderr, " %c %3d %s\n", ((i<counts[0])?' ':'*'), i, metadata[i].name);
        }
        if (counts[1]) {
          fprintf(stderr,
                  "Note: Lines marked with '*' may not be valid for all inputs and/or job layouts.\n"
                  "      The user is responsible for ensuring only valid algorithms are requested.\n"
                 );
        }
        print_once[(int)op] = 1;
      }
    } else if (isdigit(envval[0])) {
      /* integer is used just as given */
      alg = atoi(envval);
      if (alg < 0 || alg >= fullcount) {
        if (!gasneti_mynode && !print_once[(int)op]) {
          fprintf(stderr, "WARNING: Ignoring value '%d' for environment variable %s,\n"
                          "         because it is outside the range of available algorithms.\n"
                          "         Set this variable to LIST for a list of all algorithms.\n",
                           alg, envvar);
          print_once[(int)op] = 1;
        }
        alg = 0;
      }
    } else {
      /* string is used for PREFIX match */
      alg = gasnetc_find_alg(envval, metadata, fullcount);
      if (alg == fullcount) {
        if (!gasneti_mynode && !print_once[(int)op] && (envval != dfltval)) {
          fprintf(stderr, "WARNING: Ignoring value '%s' for environment variable %s,\n"
                          "         because it does not match any available algorithm.\n"
                          "         Set this variable to LIST for a list of all algorithms.\n",
                           envval, envvar);
          print_once[(int)op] = 1;
        }
        alg = 0;
      }
    }
  }

  *alg_p = algorithms[alg];
}
コード例 #5
0
ファイル: remote_update.c プロジェクト: jeffhammond/ospri
int main(int argc, char ** argv)
{
    pami_client_t         client;
    pami_context_t        context;
    pami_result_t         status = PAMI_ERROR;
    pami_configuration_t  pami_config;
    pami_geometry_t       world_geo;
    size_t                barrier_alg_num[2];
    pami_algorithm_t*     bar_always_works_algo = NULL;
    pami_metadata_t*      bar_always_works_md = NULL;
    pami_algorithm_t*     bar_must_query_algo = NULL;
    pami_metadata_t*      bar_must_query_md   = NULL;
    pami_xfer_t           barrier;
    int                   my_id;
    volatile int          is_fence_done   = 0;
    volatile int          is_barrier_done = 0;

    /* create PAMI client */
    RC( PAMI_Client_create("TEST", &client, NULL, 0) );
    DBG_FPRINTF((stderr,"Client created successfully at 0x%p\n",client));

    /* create PAMI context */
    RC( PAMI_Context_createv(client, NULL, 0, &context, 1) );
    DBG_FPRINTF((stderr,"Context created successfully at 0x%p\n",context));

    /* query my task id */
    bzero(&pami_config, sizeof(pami_configuration_t));
    pami_config.name = PAMI_CLIENT_TASK_ID;
    RC( PAMI_Client_query(client, &pami_config, 1) );
    my_id = pami_config.value.intval;
    DBG_FPRINTF((stderr,"My task id is %d\n", my_id));

    /* get the world geometry */
    RC( PAMI_Geometry_world(client, &world_geo) );
    DBG_FPRINTF((stderr,"World geometry is at 0x%p\n",world_geo));

    /* query number of barrier algorithms */
    RC( PAMI_Geometry_algorithms_num(world_geo, PAMI_XFER_BARRIER, 
                barrier_alg_num) );
    DBG_FPRINTF((stderr,"%d-%d algorithms are available for barrier op\n",
                barrier_alg_num[0], barrier_alg_num[1]));
    if (barrier_alg_num[0] <= 0) {
        fprintf (stderr, "Error. No (%lu) algorithm is available for barrier op\n",
                barrier_alg_num[0]);
        return 1;
    }

    /* query barrier algorithm list */
    bar_always_works_algo =
        (pami_algorithm_t*)malloc(sizeof(pami_algorithm_t)*barrier_alg_num[0]);
    bar_always_works_md =
        (pami_metadata_t*)malloc(sizeof(pami_metadata_t)*barrier_alg_num[0]);
    bar_must_query_algo =
        (pami_algorithm_t*)malloc(sizeof(pami_algorithm_t)*barrier_alg_num[1]);
    bar_must_query_md =
        (pami_metadata_t*)malloc(sizeof(pami_metadata_t)*barrier_alg_num[1]);

    RC( PAMI_Geometry_algorithms_query(world_geo, PAMI_XFER_BARRIER,
                bar_always_works_algo, bar_always_works_md, barrier_alg_num[0],
                bar_must_query_algo, bar_must_query_md, barrier_alg_num[1]) );
    DBG_FPRINTF((stderr,"Algorithm [%s] at 0x%p will be used for barrier op\n",
                bar_always_works_md[0].name, bar_always_works_algo[0]));

    /* begin PAMI fence */
    RC( PAMI_Fence_begin(context) );
    DBG_FPRINTF((stderr,"PAMI fence begins\n"));

    /* ------------------------------------------------------------------------ */

    pami_extension_t          extension;
    const char                ext_name[] = "EXT_hfi_extension";
    const char                sym_name[] = "hfi_remote_update";
    hfi_remote_update_fn      remote_update = NULL;
    hfi_remote_update_info_t  remote_info;
    pami_memregion_t          mem_region;
    size_t                    mem_region_sz = 0;
    unsigned long long        operand = 1234;
    unsigned long long        orig_val = 0;
    int                       offset = (operand)%MAX_TABLE_SZ;

    /* initialize table for remote update operation */
    int i;
    for (i = 0; i < MAX_TABLE_SZ; i ++) {
        table[i] = (unsigned long long) i;
    }
    orig_val = table[offset];

    /* open PAMI extension */
    RC( PAMI_Extension_open (client, ext_name, &extension) );
    DBG_FPRINTF((stderr,"Open %s successfully.\n", ext_name));

    /* load PAMI extension function */
    remote_update = (hfi_remote_update_fn) 
        PAMI_Extension_symbol (extension, sym_name);
    if (remote_update == (void *)NULL)
    {
        fprintf (stderr, "Error. Failed to load %s function in %s\n",
                 sym_name, ext_name); 
        return 1;
    } else {
        DBG_FPRINTF((stderr,"Loaded function %s in %s successfully.\n", 
                    sym_name, ext_name));
    }

    /* create a memory region for remote update operation */
    RC( PAMI_Memregion_create(context, table, 
                MAX_TABLE_SZ*sizeof(unsigned long long),
                &mem_region_sz, &mem_region) );
    DBG_FPRINTF((stderr,"%d-byte PAMI memory region created successfully.\n",
                mem_region_sz));

    /* perform a PAMI barrier */
    is_barrier_done = 0;
    barrier.cb_done = barrier_done;
    barrier.cookie = (void*)&is_barrier_done;
    barrier.algorithm = bar_always_works_algo[0];
    RC( PAMI_Collective(context, &barrier) );
    DBG_FPRINTF((stderr,"PAMI barrier op invoked successfully.\n"));
    while (is_barrier_done == 0)
        PAMI_Context_advance(context, 1000);
    DBG_FPRINTF((stderr,"PAMI barrier op finished successfully.\n"));

    RC( PAMI_Context_lock(context) );

    /* prepare remote update info */
    remote_info.dest = my_id^1;
    remote_info.op = 0;           /* op_add */
    remote_info.atomic_operand = operand;
    remote_info.dest_buf = (unsigned long long)(&(table[offset]));

    /* invoke remote update PAMI extension function */
    RC( remote_update(context, 1, &remote_info) );
    DBG_FPRINTF((stderr,"Function %s invoked successfully.\n", 
                sym_name));

    RC( PAMI_Context_unlock(context) );

    /* perform a PAMI fence */
    is_fence_done = 0;
    RC( PAMI_Fence_all(context, fence_done, (void*)&is_fence_done) );
    DBG_FPRINTF((stderr,"PAMI_Fence_all invoked successfully.\n")); 
    while (is_fence_done == 0)
        PAMI_Context_advance(context, 1000);
    DBG_FPRINTF((stderr,"PAMI_Fence_all finished successfully.\n")); 

    /* perform a PAMI barrier */
    is_barrier_done = 0;
    barrier.cb_done = barrier_done;
    barrier.cookie = (void*)&is_barrier_done;
    barrier.algorithm = bar_always_works_algo[0];
    RC( PAMI_Collective(context, &barrier) );
    DBG_FPRINTF((stderr,"PAMI barrier op invoked successfully.\n"));
    while (is_barrier_done == 0)
        PAMI_Context_advance(context, 1000);
    DBG_FPRINTF((stderr,"PAMI barrier op finished successfully.\n"));

    /* verify data after remote update operation */
    if (table[offset] != orig_val + operand) {
        printf("Data verification at offset %d with operand %lu failed: "
                "[%lu expected with %lu updated]\n",
                offset, operand, orig_val+operand, table[offset]);
    } else {
        printf("Data verification at offset %d with operand %lu passed: "
                "[%lu expected with %lu updated].\n",
                offset, operand, orig_val+operand, table[offset]);
    }

    /* destroy the memory region after remote update operation */
    RC( PAMI_Memregion_destroy(context, &mem_region) );
    DBG_FPRINTF((stderr,"PAMI memory region removed successfully.\n"));

    /* close PAMI extension */
    RC( PAMI_Extension_close (extension) );
    DBG_FPRINTF((stderr,"Close %s successfully.\n", ext_name));

    /* ------------------------------------------------------------------------ */

    /* end PAMI fence */
    RC( PAMI_Fence_end(context) );
    DBG_FPRINTF((stderr,"PAMI fence ends\n"));

    /* destroy PAMI context */
    RC( PAMI_Context_destroyv(&context, 1) );
    DBG_FPRINTF((stderr, "PAMI context destroyed successfully\n"));

    /* destroy PAMI client */
    RC( PAMI_Client_destroy(&client) );
    DBG_FPRINTF((stderr, "PAMI client destroyed successfully\n"));

    return 0;
}