text: /**
   * Copyright (c) 2009-2015 The University of Tennessee and The University
   *                         of Tennessee Research Foundation.  All rights
   *                         reserved.
   */
  
  #ifndef _VPMAP_H_
  #define _VPMAP_H_
  
  /**
   *  @defgroup parsec_internal_virtualprocess Virtual Processes
   *  @ingroup parsec_internal
   *    Virtual Processes allow to isolate groups of threads and avoid
   *    work stealing between threads belonging to different virtual
   *    processes.
   *  @addtogroup parsec_internal_virtualprocess
   *  @{
   */
  
  #include <stdio.h> /* for FILE* */
  
  BEGIN_C_DECLS
  /**
   * vpmap_fini
   * to be called when finalizing the virtual process map
   */
  void vpmap_fini(void);
  
  /* VPMAP_INIT_*
   *  Different ways of initializing the vpmap.
   * Forall XXX, YYY,
   *     vpmap_init_XXX cannot be called after a succesful call to vpmap_init_YYY
   */
  
  /**
   * Initialize the vpmap based on the HWLOC hardware locality information. Do not
   * initialize more than the expected number of cores.
   *   Create one thread per core
   *   Create one vp per socket
   *   Bind threads of the same vp on the different cores of the
   *     corresponding socket
   *   Uses hwloc
   * @return 0 if success; -1 if the initialization was not possible.
   */
  int vpmap_init_from_hardware_affinity(int nbcores);
  
  /**
   * initialize the vpmap using a simple nbvp x nbthreadspervp
   *   approach; and a round-robin distribution of threads among cores.
   */
  int vpmap_init_from_parameters(int nbvp, int nbthreadspervp, int nbcores);
  
  /**
   * initialize the vpmap using a very simple flat x nbcores approach
   */
  int vpmap_init_from_flat(int nbcores);
  
  /**
   * initialize the vpmap using a virtual process rank file
   *  Format of the rankfile:
   *  list of integers: cores of thread 0 of vp 0
   *  list of integers: cores of thread 1 of vp 0
   *  ...
   *  blank line: change the vp number
   *  list of integers: cores of thread 0 of vp 1
   *  ...
   */
  int vpmap_init_from_file(const char *filename);
  
  /* VPMAP_GET_*
   *   return information on the (local) virtual process map
   */
  
  /**
   * @return the number of virtual processes on the local process
   */
  int vpmap_get_nb_vp(void);
  
  /**
   * @param vp: identifier of the virtual process
   *        0 <= vp < vpmap_get_nb_vp()
   * @return the number of threads in this VP, or -1 if vp is not correct
   */
  typedef int (*vpmap_get_nb_threads_in_vp_t)(int vp);
  extern vpmap_get_nb_threads_in_vp_t vpmap_get_nb_threads_in_vp;
  
  /**
   * @param vp: identifier of the virtual process
   *        0 <= vp < vpmap_get_nb_vp()
   * @param thread: identifier of the thread
   *        0 <= thread < vpmap_get_nb_threads_in_vp(vp)
   * @return the number of cores on which this thread of this vp can be bound
   *         -1 if vp or thread is not compatible.
   */
  typedef int (*vpmap_get_nb_cores_affinity_t)(int vp, int thread);
  extern vpmap_get_nb_cores_affinity_t vpmap_get_nb_cores_affinity;
  
  /**
   * @param vp: identifier of the virtual process
   *        0 <= vp < vpmap_get_nb_vp()
   * @param thread: identifier of the thread
   *        0 <= thread < vpmap_get_nb_threads_in_vp(vp)
   * @param cores: output array of cores identifier on which the thread
   *               thread of the virtual process vp can be bound.
   *               sizeof(cores) = sizeof(int) * vpmap_get_nb_cores_affinity(vp, thread)
   *        cores[*] is undefined if vp or thread is not compatible
   */
  typedef void (*vpmap_get_core_affinity_t)(int vp, int thread, int *cores, int *ht);
  extern vpmap_get_core_affinity_t vpmap_get_core_affinity;
  
  /**
   * Returns the number of threads on which the current vpmap spans
   *  (sum of the get_nb_thread_in_vp for all vp)
   */
  int vpmap_get_nb_total_threads(void);
  
  /**
   * Helping function: displays the virtual process map 
   */
  void vpmap_display_map(void);
  
  END_C_DECLS
  
  /** @} */
  
  #endif
  