NAME

Sys::Hwloc - Perl Access to Portable Hardware Locality (hwloc)

SYNOPSIS

use Sys::Hwloc;

# Load topology
$topology = hwloc_topology_init();
die "Failed to init topology" unless $topology;
$rc = hwloc_topology_load($topology);
die "Failed to load topology" if $rc;

# Determine number of sockets and processors
$nProcs   = hwloc_get_nbobjs_by_type($topology, HWLOC_OBJ_PU);
$nSockets = hwloc_get_nbobjs_by_type($topology, HWLOC_OBJ_SOCKET);
die "Failed to determine number of processors" unless $nProcs;
die "Failed to determine number of sockets"    unless $nSockets;
printf "Topology contains %d processors on %d sockets.\n", $nProcs, $nSockets;

# Compute the amount of cache of the first logical processor
$levels = 0;
$size   = 0;
for($obj = hwloc_get_obj_by_type($topology, HWLOC_OBJ_PU, 0);
    $obj;
    $obj = $obj->parent
   ) {
  next unless $obj->type == HWLOC_OBJ_CACHE;
  $levels++;
  $size += $obj->attr->{cache}->{size};
}
printf "Logical CPU 0 has %d caches with total %dkB.\n", $levels, $size / 1024;

# Destroy topology
hwloc_topology_destroy($topology);

or going the OO-ish way:

       use Sys::Hwloc;

       # Load topology
       $topology = Sys::Hwloc::Topology->init;
       die "Failed to init topology" unless $topology;
       $rc = $topology->load;
       die "Failed to load topology" if $rc;

       # Determine number of sockets and processors
       $nProcs   = $topology->get_nbobjs_by_type(HWLOC_OBJ_PU);
       $nSockets = $topology->get_nbobjs_by_type(HWLOC_OBJ_SOCKET);
       die "Failed to determine number of processors" unless $nProcs;
       die "Failed to determine number of sockets"    unless $nSockets;
       printf "Topology contains %d processors on %d sockets.\n", $nProcs, $nSockets;

       # Stringify the left side of the topology tree
       for($obj = $topology->get_obj_by_depth(0,0);
           $obj;
           $obj = $obj->first_child
          ) {
         printf("%*s%s#%d (%s)\n",
	        $obj->depth, '',
	        $obj->sprintf_type,
	        $obj->logical_index,
	        $obj->sprintf_attr('; ',1),
	       );
       }

       # Destroy topology
       $topology->destroy;

DESCRIPTION

The Sys::Hwloc module provides a Perl wrapper API around the Portable Hardware Locality (hwloc) C API.

Visit http://www.open-mpi.org/projects/hwloc for information about hwloc.

The module provides access to the functions of the hwloc API as well as an object-oriented interface to hwloc_topology, hwloc_obj and hwloc_cpuset objects.

EXPORT/IMPORT

The Sys::Hwloc module exports constants and functions of the hwloc core ABI and basic helpers by default. To import these, load the module with one of the following:

use Sys::Hwloc;
use Sys::Hwloc qw(:DEFAULT);

Names of constants and functions belonging to the Cpuset API, the Bitmap API and the Binding API have to be imported explicitely.

Examples:

use Sys::Hwloc qw(:DEFAULT :cpuset);
use Sys::Hwloc qw(:DEFAULT :bitmap :binding);

To get a list of what is exported by default, type:

perl -MSys::Hwloc -MData::Dumper -e 'print Dumper(\@Sys::Hwloc::EXPORT)'

To get a list of optional symbols, type:

perl -MSys::Hwloc -MData::Dumper -e 'print Dumper(\%Sys::Hwloc::EXPORT_TAGS)'

CONSTANTS

The following constants are exported by the Sys::Hwloc module:

Type of topology objects

HWLOC_OBJ_MACHINE
HWLOC_OBJ_NODE
HWLOC_OBJ_SOCKET
HWLOC_OBJ_CACHE
HWLOC_OBJ_CORE
HWLOC_OBJ_PROC                                     before hwloc-1.0
HWLOC_OBJ_PU                                       since  hwloc-1.0
HWLOC_OBJ_GROUP                                    since  hwloc-1.0
HWLOC_OBJ_MISC

Topology flags

HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM
HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM

Misc

HWLOC_API_VERSION                                  undef before hwloc-1.0
HWLOC_XSAPI_VERSION                                0     before hwloc-1.0
HWLOC_HAS_XML                                      hwloc built with XML or not
HWLOC_TYPE_UNORDERED
HWLOC_TYPE_DEPTH_UNKNOWN
HWLOC_TYPE_DEPTH_MULTIPLE

METHODS

The following methods are exported by default.

Each listing contains the methods that conform to the hwloc C API, and the corresponding Hwloc perl API OO-ish methods, if implemented.

Create and destroy topologies

$t    = hwloc_topology_init()
$rc   = hwloc_topology_load($t)
hwloc_topology_check($t)
hwloc_topology_destroy($t)

$t    = Sys::Hwloc::Topology->init
$t    = Sys::Hwloc::Topology->new
$rc   = $t->load
$t->check
$t->destroy

Configure topology detection

$rc   = hwloc_topology_ignore_type($t,$type)
$rc   = hwloc_topology_ignore_type_keep_structure($t,$type)
$rc   = hwloc_topology_ignore_all_keep_structure($t)
$rc   = hwloc_topology_set_flags($t,$flags)
$rc   = hwloc_topology_set_fsroot($t,$path)
$rc   = hwloc_topology_set_pid($t,$pid)                   since  hwloc-1.0
$rc   = hwloc_topology_set_synthetic($t,$string)
$rc   = hwloc_topology_set_xml($t,$path)
$href = hwloc_topology_get_support($t)                    since  hwloc-1.0

$rc   = $t->ignore_type($type)
$rc   = $t->ignore_type_keep_structure($type)
$rc   = $t->ignore_all_keep_structure
$rc   = $t->set_flags($flags)
$rc   = $t->set_fsroot($path)
$rc   = $t->set_pid($pid)                                 since  hwloc-1.0
$rc   = $t->set_synthetic($string)
$rc   = $t->set_xml($path)
$href = $t->get_support                                   since  hwloc-1.0

Tinker with topologies

hwloc_topology_export_xml($t,$path)                       if HWLOC_HAS_XML

$t->export_xml($path)                                     if HWLOC_HAS_XML

Get some topology information

$val  = hwloc_topology_get_depth($t)
$val  = hwloc_topology_get_type_depth($t,$type)
$val  = hwloc_topology_get_depth_type($t,$depth)
$val  = hwloc_get_nbobjs_by_depth($t,$depth)
$val  = hwloc_get_nbobjs_by_type($t,$type)
$rc   = hwloc_topology_is_thissystem($t)

$val  = $t->depth
$val  = $t->get_type_depth($type)
$val  = $t->get_depth_type($depth)
$val  = $t->get_nbobjs_by_depth($depth)
$val  = $t->get_nbobjs_by_type($type)
$rc   = $t->is_thissystem

Retrieve topology objects

$obj  = hwloc_get_obj_by_depth($t,$depth,$idx)
$obj  = hwloc_get_obj_by_type($t,$type,$idx)

$obj  = $t->get_obj_by_depth($depth,$idx)
$obj  = $t->get_obj_by_type($type,$idx)

Topology object properties

$val  = $obj->type
$val  = $obj->os_index
$val  = $obj->name
$href = $obj->memory                                      since  hwloc-1.0
$href = $obj->attr                                        since  hwloc-1.0
$val  = $obj->depth
$val  = $obj->logical_index
$val  = $obj->os_level
$obj  = $obj->next_cousin
$obj  = $obj->prev_cousin
$obj  = $obj->father                                      before hwloc-1.0
$obj  = $obj->parent                                      since  hwloc-1.0
$val  = $obj->sibling_rank
$obj  = $obj->next_sibling
$obj  = $obj->prev_sibling
$val  = $obj->arity
@objs = $obj->children
$obj  = $obj->first_child
$obj  = $obj->last_child
$set  = $obj->cpuset
$set  = $obj->complete_cpuset                             since  hwloc-1.0
$set  = $obj->online_cpuset                               since  hwloc-1.0
$set  = $obj->allowed_cpuset                              since  hwloc-1.0
$set  = $obj->nodeset                                     since  hwloc-1.0
$set  = $obj->complete_nodeset                            since  hwloc-1.0
$set  = $obj->allowed_nodeset                             since  hwloc-1.0
$href = $obj->infos                                       since  hwloc-1.1

Object/string conversion

$val  = hwloc_obj_type_string($type)
$val  = hwloc_obj_type_of_string($string)
$val  = hwloc_obj_type_sprintf($obj,$verbose)             since  hwloc-1.0
$val  = hwloc_obj_attr_sprintf($obj,$separator,$verbose)  since  hwloc-1.0
$val  = hwloc_obj_cpuset_sprintf($obj1,$obj2,...)
$val  = hwloc_obj_sprintf($t,$obj,$prefix,$verbose)
$val  = hwloc_obj_get_info_by_name($obj,$string)          since  hwloc-1.1

$val  = $obj->sprintf_type($verbose)                      since  hwloc-1.0
$val  = $obj->sprintf_attr($separator,$verbose)           since  hwloc-1.0
$val  = $obj->sprintf_cpuset
$val  = $t->sprintf_obj($obj,$prefix,$verbose)
$val  = $obj->sprintf($prefix,$verbose)
$val  = $obj->info_by_name($string)                       since  hwloc-1.1

Object type helpers

$val  = hwloc_compare_types($type1,$type2)

$val  = hwloc_get_type_or_below_depth($t,$type)
$val  = hwloc_get_type_or_above_depth($t,$type)

$val  = $t->get_type_or_below_depth($type)
$val  = $t->get_type_or_above_depth($type)

Traversal helpers

$obj  = hwloc_get_system_obj($t)                                   before hwloc-1.0
$obj  = hwloc_get_root_obj($t)                                     since  hwloc-1.0
$obj  = hwloc_get_ancestor_obj_by_depth($obj,$depth)               since  hwloc-1.0
$obj  = hwloc_get_ancestor_obj_by_type($obj,$type)                 since  hwloc-1.0
$obj  = hwloc_get_next_obj_by_depth($t,$depth,$obj)
$obj  = hwloc_get_next_obj_by_type($t,$type,$obj)
$obj  = hwloc_get_pu_obj_by_os_index($t,$idx)                      since  hwloc-1.0
$obj  = hwloc_get_next_child($obj,$childobj)
$obj  = hwloc_get_common_ancestor_obj($t,$obj1,$obj2)
$rc   = hwloc_obj_is_in_subtree($t,$obj1,$obj2)
@objs = hwloc_get_closest_objs($t,$obj)
$obj  = hwloc_get_obj_below_by_type($t,$type1,$idx1,$type2,$idx2)  since hwloc-1.0
$rc   = hwloc_compare_objects($t,$obj1,$obj2)                      not in hwloc

$obj  = $t->system                                                 before hwloc-1.0
$obj  = $t->root                                                   since  hwloc-1.0
$obj  = $obj->ancestor_by_depth($depth)                            since  hwloc-1.0
$obj  = $obj->ancestor_by_type($type)                              since  hwloc-1.0
$obj  = $t->get_next_obj_by_depth($depth,$obj)
$obj  = $t->get_next_obj_by_type($type,$obj)
$obj  = $t->get_pu_obj_by_os_index($idx)                           since  hwloc-1.0
$obj  = $obj->next_child($childobj)
$obj  = $t->get_common_ancestor_obj($obj1,$obj2)
$obj  = $obj->common_ancestor($obj)
$rc   = $t->obj_is_in_subtree($obj1,$obj2)
$rc   = $obj->is_in_subtree($obj)
@objs = $t->get_closest_objs($obj)
$obj  = $t->get_obj_below_by_type($type1,$idx1,$type2,$idx2)       since hwloc-1.0
$rc   = $t->compare_objects($obj1,$obj2)                           not in hwloc
$rc   = $obj->is_same_obj($obj)                                    not in hwloc

CPUSET API (before hwloc-1.1)

The hwloc C API of hwloc-0.9 and 1.0 defines the Cpuset API.

The Sys::Hwloc module exports the corresponding methods and some utility functions, when requested with

use Sys::Hwloc qw(:DEFAULT :cpuset);

Cpuset API

$set  = hwloc_cpuset_alloc
$seta = hwloc_cpuset_dup($set)
$set  = hwloc_cpuset_from_string($string)                 before hwloc-1.0
hwloc_cpuset_free($set)
hwloc_cpuset_copy($dstset,$srcset)
hwloc_cpuset_zero($set)
hwloc_cpuset_fill($set)
hwloc_cpuset_cpu($set,$id)
hwloc_cpuset_all_but_cpu($set,$id)
hwloc_cpuset_from_ulong($set,$mask)
hwloc_cpuset_from_ith_ulong($set,$i,$mask)
$rc   = hwloc_cpuset_from_string($set,$string)            since  hwloc-1.0
$rc   = hwloc_cpuset_from_liststring($set,$string)        not in hwloc
hwloc_cpuset_set($set,$id)
hwloc_cpuset_set_range($set,$ida,$ide)
hwloc_cpuset_set_ith_ulong($set,$i,$mask)
hwloc_cpuset_clr($set,$id)
hwloc_cpuset_clr_range($set,$ida1,$ide)                   since  hwloc-1.0
hwloc_cpuset_singlify($set)
$val  = hwloc_cpuset_to_ulong($set)
$val  = hwloc_cpuset_to_ith_ulong($set,$i)
$val  = hwloc_cpuset_sprintf($set)
$val  = hwloc_cpuset_list_sprintf($set)                   not in hwloc
@vals = hwloc_cpuset_ids($set)                            not in hwloc
$rc   = hwloc_cpuset_isset($set,$id)
$rc   = hwloc_cpuset_iszero($set)
$rc   = hwloc_cpuset_isfull($set)
$val  = hwloc_cpuset_first($set)
$val  = hwloc_cpuset_next($set,$prev)                     since  hwloc-1.0
$val  = hwloc_cpuset_last($set)
$val  = hwloc_cpuset_weight($set)
hwloc_cpuset_orset($set,$seta)                            before hwloc-1.0
hwloc_cpuset_andset($set,$seta)                           before hwloc-1.0
hwloc_cpuset_xorset($set,$seta)                           before hwloc-1.0
hwloc_cpuset_or($set,$seta,$setb)                         since  hwloc-1.0
hwloc_cpuset_and($set,$seta,$setb)                        since  hwloc-1.0
hwloc_cpuset_andnot($set,$seta,$setb)                     since  hwloc-1.0
hwloc_cpuset_xor($set,$seta,$setb)                        since  hwloc-1.0
hwloc_cpuset_not($set,$seta)                              since  hwloc-1.0
$rc   = hwloc_cpuset_intersects($seta,$setb)
$rc   = hwloc_cpuset_includes($seta,$setb)                not in hwloc
$rc   = hwloc_cpuset_isincluded($seta,$setb)
$rc   = hwloc_cpuset_isequal($seta,$setb)
$rc   = hwloc_cpuset_compar($seta,$setb)                  before hwloc-1.0
$rc   = hwloc_cpuset_compar_first($seta,$setb)            before hwloc-1.0
$rc   = hwloc_cpuset_compare($seta,$setb)                 since  hwloc-1.0
$rc   = hwloc_cpuset_compare_first($seta,$setb)           since  hwloc-1.0

$set  = Sys::Hwloc::Cpuset->alloc
$set  = Sys::Hwloc::Cpuset->new
$seta = $set->dup
$set->free
$set->destroy
$set->copy($seta)
$set->zero
$set->fill
$set->cpu($id)
$set->all_but_cpu($id)
$set->from_ulong($mask)
$set->from_ith_ulong($i,$mask)
$rc   = $set->from_string($string)                        since  hwloc-1.0
$rc   = $set->from_liststring($string)                    not in hwloc
$set->set($id)
$set->set_range($ida,$ide)
$set->set_ith_ulong($i,$mask)
$set->clr($id)
$set->clr_range($ida,$ide)                                since  hwloc-1.0
$set->singlify
$val  = $set->to_ulong
$val  = $set->to_ith_ulong($i)
$val  = $set->sprintf
$val  = $set->sprintf_list                                not in hwloc
@vals = $set->ids                                         not in hwloc
$rc   = $set->isset($id)
$rc   = $set->iszero
$rc   = $set->isfull
$val  = $set->first
$val  = $set->next($prev)
$val  = $set->last
$val  = $set->weight
$set->or($seta)
$set->and($seta)
$set->andnot($seta)                                       since  hwloc-1.0
$set->xor($seta)
$set->not                                                 since  hwloc-1.0
$rc   = $set->intersects($seta)
$rc   = $set->includes($seta)                             not in hwloc
$rc   = $set->isincluded($seta)
$rc   = $set->isequal($seta)
$rc   = $set->compar($seta)                               before hwloc-1.0
$rc   = $set->compar_first($seta)                         before hwloc-1.0
$rc   = $set->compare($seta)                              since  hwloc-1.0
$rc   = $set->compare_first($seta)                        since  hwloc-1.0

Cpuset and Nodeset helpers

$set  = hwloc_topology_get_complete_cpuset($t)            since  hwloc-1.0
$set  = hwloc_topology_get_topology_cpuset($t)            since  hwloc-1.0
$set  = hwloc_topology_get_online_cpuset($t)              since  hwloc-1.0
$set  = hwloc_topology_get_allowed_cpuset($t)             since  hwloc-1.0
$rc   = hwloc_get_nbobjs_inside_cpuset_by_depth($t,$set,$depth)
$rc   = hwloc_get_nbobjs_inside_cpuset_by_type($t,$set,$type)
$obj  = hwloc_get_obj_inside_cpuset_by_depth($t,$set,$depth)
$obj  = hwloc_get_obj_inside_cpuset_by_type($t,$set,$type)
$obj  = hwloc_get_next_obj_inside_cpuset_by_depth($t,$set,$depth,$prev)
$obj  = hwloc_get_next_obj_inside_cpuset_by_type($t,$set,$type,$prev)
$obj  = hwloc_get_first_largest_obj_inside_cpuset($t,$set) since hwloc-1.0
@objs = hwloc_get_largest_objs_inside_cpuset($t,$set)

$set  = $t->get_complete_cpuset                           since  hwloc-1.0
$set  = $t->get_topology_cpuset                           since  hwloc-1.0
$set  = $t->get_online_cpuset                             since  hwloc-1.0
$set  = $t->get_allowed_cpuset                            since  hwloc-1.0
$rc   = $t->get_nbobjs_inside_cpuset_by_depth($set,$depth)
$rc   = $t->get_nbobjs_inside_cpuset_by_type($set,$type)
$obj  = $t->get_obj_inside_cpuset_by_depth($set,$depth)
$obj  = $t->get_obj_inside_cpuset_by_type($set,$type)
$obj  = $t->get_next_obj_inside_cpuset_by_depth($set,$depth,$prev)
$obj  = $t->get_next_obj_inside_cpuset_by_type($set,$type,$prev)
$obj  = $t->get_first_largest_obj_inside_cpuset($set)
@objs = $t->get_largest_objs_inside_cpuset($set)

BITMAP API (since hwloc-1.1)

The hwloc C API since hwloc-1.1 defines the Bitmap API, which replaces the Cpuset API.

The Sys::Hwloc module exports the corresponding methods and some utility functions, when requested with

use Sys::Hwloc qw(:DEFAULT :bitmap);

Bitmap API

$map  = hwloc_bitmap_alloc
$map  = hwloc_bitmap_alloc_full
$mapa = hwloc_bitmap_dup($map)
hwloc_bitmap_free($map)
hwloc_bitmap_copy($dstmap,$srcmap)
hwloc_bitmap_zero($map)
hwloc_bitmap_fill($map)
hwloc_bitmap_only($map,$id)
hwloc_bitmap_allbut($map,$id)
hwloc_bitmap_from_ulong($map,$mask)
hwloc_bitmap_from_ith_ulong($map,$i,$mask)
$rc   = hwloc_bitmap_sscanf($map,$string)
$rc   = hwloc_bitmap_list_sscanf($map,$string)            not in hwloc
$rc   = hwloc_bitmap_taskset_sscanf($map,$string)
hwloc_bitmap_set($map,$id)
hwloc_bitmap_set_range($map,$ida,$ide)
hwloc_bitmap_set_ith_ulong($map,$i,$mask)
hwloc_bitmap_clr($map,$id)
hwloc_bitmap_clr_range($map,$ida1,$ide)
hwloc_bitmap_singlify($map)
$val  = hwloc_bitmap_to_ulong($map)
$val  = hwloc_bitmap_to_ith_ulong($map,$i)
$val  = hwloc_bitmap_sprintf($map)
$val  = hwloc_bitmap_list_sprintf($map)                   not in hwloc
$val  = hwloc_bitmap_taskset_sprintf($map)
@vals = hwloc_bitmap_ids($map)                            not in hwloc
$rc   = hwloc_bitmap_isset($map,$id)
$rc   = hwloc_bitmap_iszero($map)
$rc   = hwloc_bitmap_isfull($map)
$val  = hwloc_bitmap_first($map)
$val  = hwloc_bitmap_next($map,$prev)
$val  = hwloc_bitmap_last($map)
$val  = hwloc_bitmap_weight($map)
hwloc_bitmap_or($map,$mapa,$mapb)
hwloc_bitmap_and($map,$mapa,$mapb)
hwloc_bitmap_andnot($map,$mapa,$mapb)
hwloc_bitmap_xor($map,$mapa,$mapb)
hwloc_bitmap_not($map,$mapa)
$rc   = hwloc_bitmap_intersects($mapa,$mapb)
$rc   = hwloc_bitmap_includes($mapa,$mapb)                not in hwloc
$rc   = hwloc_bitmap_isincluded($mapa,$mapb)
$rc   = hwloc_bitmap_isequal($mapa,$mapb)
$rc   = hwloc_bitmap_compare($mapa,$mapb)
$rc   = hwloc_bitmap_compare_first($mapa,$mapb)

$map  = Sys::Hwloc::Bitmap->alloc
$map  = Sys::Hwloc::Bitmap->new
$map  = Sys::Hwloc::Bitmap->alloc_full
$mapa = $map->dup
$map->free
$map->destroy
$map->copy($mapa)
$map->zero
$map->fill
$map->only($id)
$map->allbut($id)
$map->from_ulong($mask)
$map->from_ith_ulong($i,$mask)
$rc   = $map->sscanf($string)
$rc   = $map->sscanf_list($string)                        not in hwloc
$rc   = $map->sscanf_taskset($string)
$map->set($id)
$map->set_range($ida,$ide)
$map->set_ith_ulong($i,$mask)
$map->clr($id)
$map->clr_range($ida,$ide)
$map->singlify
$val  = $map->to_ulong
$val  = $map->to_ith_ulong($i)
$val  = $map->sprintf
$val  = $map->sprintf_list
$val  = $map->sprintf_taskset
@vals = $map->ids                                         not in hwloc
$rc   = $map->isset($id)
$rc   = $map->iszero
$rc   = $map->isfull
$val  = $map->first
$val  = $map->next($prev)
$val  = $map->last
$val  = $map->weight
$map->or($mapa)
$map->and($mapa)
$map->andnot($mapa)
$map->xor($mapa)
$map->not
$rc   = $map->intersects($mapa)
$rc   = $map->includes($mapa)                             not in hwloc
$rc   = $map->isincluded($mapa)
$rc   = $map->isequal($mapa)
$rc   = $map->compare($mapa)
$rc   = $map->compare_first($mapa)

Cpuset and Nodeset helpers

$set  = hwloc_topology_get_complete_cpuset($t)
$set  = hwloc_topology_get_topology_cpuset($t)
$set  = hwloc_topology_get_online_cpuset($t)
$set  = hwloc_topology_get_allowed_cpuset($t)
$set  = hwloc_topology_get_complete_nodeset($t)
$set  = hwloc_topology_get_topology_nodeset($t)
$set  = hwloc_topology_get_allowed_nodeset($t)
hwloc_cpuset_to_nodeset($t,$cpuset,$nodeset)
hwloc_cpuset_to_nodeset_strict($t,$cpuset,$nodeset)
hwloc_cpuset_from_nodeset($t,$cpuset,$nodeset)
hwloc_cpuset_from_nodeset_strict($t,$cpuset,$nodeset)
$rc   = hwloc_get_nbobjs_inside_cpuset_by_depth($t,$set,$depth)
$rc   = hwloc_get_nbobjs_inside_cpuset_by_type($t,$set,$type)
$obj  = hwloc_get_obj_inside_cpuset_by_depth($t,$set,$depth)
$obj  = hwloc_get_obj_inside_cpuset_by_type($t,$set,$type)
$obj  = hwloc_get_next_obj_inside_cpuset_by_depth($t,$set,$depth,$prev)
$obj  = hwloc_get_next_obj_inside_cpuset_by_type($t,$set,$type,$prev)
$obj  = hwloc_get_first_largest_obj_inside_cpuset($t,$set)
@objs = hwloc_get_largest_objs_inside_cpuset($t,$set)

$set  = $t->get_complete_cpuset
$set  = $t->get_topology_cpuset
$set  = $t->get_online_cpuset
$set  = $t->get_allowed_cpuset
$set  = $t->get_complete_nodeset
$set  = $t->get_topology_nodeset
$set  = $t->get_allowed_nodeset
$t->cpuset_to_nodeset($cpuset,$nodeset)
$t->cpuset_to_nodeset_strict($cpuset,$nodeset)
$t->cpuset_from_nodeset($cpuset,$nodeset)
$t->cpuset_from_nodeset_strict($cpuset,$nodeset)
$rc   = $t->get_nbobjs_inside_cpuset_by_depth($set,$depth)
$rc   = $t->get_nbobjs_inside_cpuset_by_type($set,$type)
$obj  = $t->get_obj_inside_cpuset_by_depth($set,$depth)
$obj  = $t->get_obj_inside_cpuset_by_type($set,$type)
$obj  = $t->get_next_obj_inside_cpuset_by_depth($set,$depth,$prev)
$obj  = $t->get_next_obj_inside_cpuset_by_type($set,$type,$prev)
$obj  = $t->get_first_largest_obj_inside_cpuset($set)
@objs = $t->get_largest_objs_inside_cpuset($set)

BINDING API

The hwloc C API provides constants and functions to bind processes or threads to cpusets or nodesets.

The Sys::Hwloc module exports the corresponding constants and methods, when requested with

use Sys::Hwloc qw(:DEFAULT :binding);

It is required to import Cpuset or Bitmap API functions in addition, when cpusets or nodesets have to be created or manipulated with the classic (not OO) interface.

CPU binding

HWLOC_CPUBIND_PROCESS
HWLOC_CPUBIND_THREAD
HWLOC_CPUBIND_STRICT
HWLOC_CPUBIND_NOMEMBIND                                   since  hwloc-1.1

$rc   = hwloc_set_cpubind($t,$set,$flags)
$rc   = hwloc_get_cpubind($t,$set,$flags)                 since  hwloc-1.0
$rc   = hwloc_set_proc_cpubind($t,$pid,$set,$flags)
$rc   = hwloc_get_proc_cpubind($t,$set,$pid,$flags)       since  hwloc-1.0

$rc   = $t->set_cpubind($set,$flags)
$rc   = $t->set_proc_cpubind($pid,$set,$flags)
$rc   = $t->get_cpubind($set,$flags)                      since  hwloc-1.0
$rc   = $t->get_proc_cpubind($pid,$set,$flags)            since  hwloc-1.0

Memory binding (since hwloc-1.1)

HWLOC_MEMBIND_PROCESS
HWLOC_MEMBIND_THREAD
HWLOC_MEMBIND_STRICT
HWLOC_MEMBIND_MIGRATE
HWLOC_MEMBIND_NOCPUBIND

HWLOC_MEMBIND_DEFAULT
HWLOC_MEMBIND_FIRSTTOUCH
HWLOC_MEMBIND_BIND
HWLOC_MEMBIND_INTERLEAVE
HWLOC_MEMBIND_REPLICATE
HWLOC_MEMBIND_NEXTTOUCH

$rc   = hwloc_set_membind($t,$set,$policy,$flags)
$rc   = hwloc_set_membind_nodeset($t,$set,$policy,$flags)
$rc   = hwloc_set_proc_membind($t,$pid,$set,$policy,$flags)
$rc   = hwloc_set_proc_membind_nodeset($t,$pid,$set,$policy,$flags)
$rc   = hwloc_get_membind($t,$set,\$policy,$flags)
$rc   = hwloc_get_membind_nodeset($t,$set,\$policy,$flags)
$rc   = hwloc_get_proc_membind($t,$pid,$set,\$policy,$flags)
$rc   = hwloc_get_proc_membind_nodeset($t,$pid,$set,\$policy,$flags)

$rc   = $t->set_membind($set,$policy,$flags)
$rc   = $t->set_membind_nodeset($set,$policy,$flags)
$rc   = $t->set_proc_membind($pid,$set,$policy,$flags)
$rc   = $t->set_proc_membind_nodeset($pid,$set,$policy,$flags)
$rc   = $t->get_membind($set,\$policy,$flags)
$rc   = $t->get_membind_nodeset($set,\$policy,$flags)
$rc   = $t->get_proc_membind($pid,$set,\$policy,$flags)
$rc   = $t->get_proc_membind_nodeset($pid,$set,\$policy,$flags)

IMPLEMENTATION SPECIFICS

Hwloc Version

The Sys::Hwloc Perl module becomes bound at compile time to a specific hwloc C library version. Depending on the version of the hwloc C library, different methods are exported.

The compile-time hwloc API version number is available to a Perl script via the constants HWLOC_API_VERSION and HWLOC_XSAPI_VERSION. At the time of writing of this document, the values are as follows:

hwloc-version  HWLOC_API_VERSION  HWLOC_XSAPI_VERSION
-------------  -----------------  -------------------
hwloc-0.9.x    undef              0
hwloc-1.0.x    0x00010000         0x00010000
hwloc-1.1.x    0x00010100         0x00010100

To bind a Perl script to a specific hwloc API version, check it in a BEGIN block:

BEGIN {
  if(HWLOC_XSAPI_VERSION() < 0x00010100) {
    die "This script needs at least hwloc-1.1";
  }
}

Object Oriented Interface

The hwloc C API defines data structures and provides functions that take pointers to variables of type struct as arguments. The hwloc C API is not object-oriented.

The Sys::Hwloc Perl module blesses the basic hwloc C data structures into separate name spaces. Thus these become Perl objects. The relation between hwloc C types and Perl classes is as follows:

C type            Perl class
---------------   --------------------
hwloc_topology_t  Sys::Hwloc::Topology
hwloc_obj_t       Sys::Hwloc::Obj
hwloc_cpuset_t    Sys::Hwloc::Cpuset
hwloc_bitmap_t    Sys::Hwloc::Bitmap

The Sys::Hwloc module provides methods that have the same name like their hwloc C API counterparts. This is the classic interface. A Perl script that uses the classic interface looks almost the same like the corresponding C source code.

In addition, the Sys::Hwloc module provides aliases to most hwloc C API functions as methods in Sys::Hwloc classes. In particular, all C functions that take a hwloc_topology_t pointer as first argument, are also accessible as methods of the Sys::Hwloc::Topology class. The same holds for the other Sys::Hwloc classes.

Examples:

classic                                 object-oriented
----------------------------------      ------------------
hwloc_topology_load($topo)              $topo->load
hwloc_topology_get_depth($topo)         $topo->depth
hwloc_topology_get_root_obj($topo)      $topo->root
hwloc_obj_type_sprintf($obj,$verbose)   $obj->sprintf_type($verbose)
hwloc_obj_get_info_by_name($obj,$name)  $obj->info_by_name($name)
hwloc_cpuset_free($cpuset)              $cpuset->free
hwloc_cpuset_isequal($set1,$set2)       $set1->isequal($set2)
hwloc_bitmap_zero($bitmap)              $bitmap->zero
hwloc_bitmap_only($bitmap,$id)          $bitmap->only($id)

Note that there is no DESTROY method in any Sys::Hwloc class, that may destroy an object and its underlying C data automatically when its reference count goes to zero. It is required to call the free-ing hwloc API functions explicitely, when allocated memory needs to be freed.

Example:

$topo = Sys::Hwloc::Topology->init; # allocates memory.
# $topo = undef;                    # WRONG, does not free!
$topo->destroy;                     # OK, frees.
# hwloc_topology_destroy($topo);    # also OK, same as above.

Cpusets, Nodesets, Bitmaps

In hwloc-0.9 and 1.0 a hwloc_obj struct defines the struct member cpuset with C type hwloc_cpuset. In hwloc-1.0 the struct member nodeset was added with C type hwloc_cpuset. Data of type hwloc_cpuset become created and manipulated with functions of the Cpuset API.

When build with these hwloc versions, the Sys::Hwloc module exports the functions of the Cpuset API on request, blesses these data into the namespace Sys::Hwloc::Cpuset, and provides OO-ish methods for them. The namespace Sys::Hwloc::Bitmap does not exist.

In hwloc-1.1 a hwloc_obj struct defines struct members with C type hwloc_cpuset, and struct members with C type hwloc_nodeset. Both C types are aliases of the C type hwloc_bitmap. These data become created and manipulated with functions of the Bitmap API.

When built with these hwloc versions, the Sys::Hwloc module exports the functions of the Bitmap API on request, blesses these data into the namespace Sys::Hwloc::Bitmap, and provides OO-ish methods for them. A distrinction between the C types hwloc_cpuset and hwloc_nodeset is not made. The namespace Sys::Hwloc::Cpuset does not exist.

Example:

use Sys::Hwloc qw(:DEFAULT :cpuset :bitmap);

if(HWLOC_XSAPI_VERSION() <= 0x00010000) {
  $set = hwloc_cpuset_alloc();
  $set->cpu(0);
} else {
  $set = hwloc_bitmap_alloc();
  $set->only(0);
}
$set->free;

Stringifying Functions

The hwloc C API contains functions that stringify topology objects, cpusets or bitmaps into something human-readable. These functions are named hwloc_*_snprintf* or hwloc_*_asprintf*, and act like snprintf or asprintf, except that they do not take a format argument.

These functions do not exist in Sys::Hwloc. They were replaced by simple hwloc_*_sprintf*, which return a new string like the Perl sprintf function does. In the case of error, undef is returned.

Example:

/* This is C */
char s[128];
int  rc;
rc = hwloc_obj_type_snprintf(s, sizeof(s), obj, 1);
printf("%s\n", s);

# This is Perl
printf "%s\n", hwloc_obj_type_sprintf($obj, 1); # classic interface
printf "%s\n", $obj->sprintf_type(1);           # OO interface

Functions that return arrays

The hwloc C API contains functions, that take a pointer to a pre-allocated array of topology objects as parameter. The functions fill the array and return the number of objects in the result array. On error, -1 is returned. These functions are

hwloc_get_closest_objs
hwloc_get_largest_objs_inside_cpuset

The corresponding Sys::Hwloc functions don't take an array pointer parameter, and return an array of Sys::Hwloc::Obj instances, instead. The result array will contain zero to max. 1024 objects. On error, the result array will be empty.

Example:

/* This is C */
hwloc_obj_t *objs;
int          rc;
objs = (hwloc_obj_t *)malloc(1024 * sizeof(hwloc_obj_t *));
rc   = hwloc_get_largest_objs_inside_cpuset(topo, set, objs, 1024);
printf("found %d objects\n", rc);
free(objs);

# This is Perl
@objs = hwloc_get_largest_objs_inside_cpuset($topo, $set);
printf "found %d objects\n", scalar @objs;

Functions not in the hwloc C API

The Sys::Hwloc module provides some functions, which are not part of the hwloc C API. These functions are provided for convenience with the hope that they are useful somehow. Maybe they occur in future hwloc versions. These are:

HWLOC_XSAPI_VERSION         always returns a version number (may be 0)
HWLOC_HAS_XML               flag if hwloc was built with XML support
hwloc_compare_objects       compares two Sys::Hwloc::Obj by C pointer value
hwloc_bitmap_list_sscanf    parses  a list format cpuset ASCII string
hwloc_bitmap_list_sprintf   outputs a list format cpuset ASCII string
hwloc_bitmap_ids            returns bitmap bits as list of decimal numbers
hwloc_bitmap_includes       reverse of hwloc_bitmap_isincluded

BUGS

Note that the Sys::Hwloc module is a wrapper, which depends on the underlying hwloc C library.

If you feel that you found a hwloc bug, refer to http://www.open-mpi.org/projects/hwloc/ how to report it.

If you feel that you found a wrapper bug, report it via https://rt.cpan.org/.

SEE ALSO

hwloc(7), Sys::Hwloc::Topology(3pm), Sys::Hwloc::Obj(3pm), Sys::Hwloc::Cpuset(3pm), Sys::Hwloc::Bitmap(3pm)

AUTHOR

Bernd Kallies, <kallies@zib.de>

COPYRIGHT AND LICENSE

Copyright (C) 2011 Zuse Institute Berlin

This package and its accompanying libraries is free software; you can redistribute it and/or modify it under the terms of the GPL version 2.0, or the Artistic License 2.0. Refer to LICENSE for the full license text.