PLASMA  2.4.5
PLASMA - Parallel Linear Algebra for Scalable Multi-core Architectures
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
control.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include "common.h"
#include "auxiliary.h"
#include "allocate.h"
Include dependency graph for control.c:

Go to the source code of this file.

Functions

void plasma_barrier_init (plasma_context_t *plasma)
void plasma_barrier_finalize (plasma_context_t *plasma)
void plasma_barrier (plasma_context_t *plasma)
void * plasma_parallel_section (void *plasma_ptr)
int PLASMA_Init (int cores)
int PLASMA_Init_Affinity (int cores, int *coresbind)
int PLASMA_Finalize ()

Detailed Description

PLASMA auxiliary routines PLASMA is a software package provided by Univ. of Tennessee, Univ. of California Berkeley and Univ. of Colorado Denver

Version:
2.4.5
Author:
Jakub Kurzak
Date:
2010-11-15

Definition in file control.c.


Function Documentation

void plasma_barrier ( plasma_context_t plasma)

Busy-waiting barrier

Definition at line 59 of file control.c.

References plasma_context_struct::barrier_id, plasma_context_struct::barrier_nblocked_thrds, plasma_context_struct::barrier_synccond, plasma_context_struct::barrier_synclock, PLASMA_RANK, PLASMA_SIZE, pthread_cond_broadcast(), pthread_cond_wait(), pthread_mutex_lock(), and pthread_mutex_unlock().

{
#ifdef BUSY_WAITING
int core;
if (PLASMA_RANK == 0) {
for (core = 1; core < PLASMA_SIZE; core++)
while (plasma->barrier_in[core] == 0);
for (core = 1; core < PLASMA_SIZE; core++)
plasma->barrier_in[core] = 0;
for (core = 1; core < PLASMA_SIZE; core++)
plasma->barrier_out[core] = 1;
}
else
{
plasma->barrier_in[PLASMA_RANK] = 1;
while (plasma->barrier_out[PLASMA_RANK] == 0);
plasma->barrier_out[PLASMA_RANK] = 0;
}
#else
int id;
id = plasma->barrier_id;
if (plasma->barrier_nblocked_thrds == PLASMA_SIZE) {
plasma->barrier_id++;
}
while (id == plasma->barrier_id)
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

void plasma_barrier_finalize ( plasma_context_t plasma)

Busy-waiting barrier finalize

Definition at line 48 of file control.c.

References plasma_context_struct::barrier_synccond, plasma_context_struct::barrier_synclock, pthread_cond_destroy(), and pthread_mutex_destroy().

{
#ifndef BUSY_WAITING
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

void plasma_barrier_init ( plasma_context_t plasma)

Busy-waiting barrier initialization

Definition at line 28 of file control.c.

References plasma_context_struct::barrier_id, plasma_context_struct::barrier_nblocked_thrds, plasma_context_struct::barrier_synccond, plasma_context_struct::barrier_synclock, CONTEXT_THREADS_MAX, pthread_cond_init(), and pthread_mutex_init().

{
#ifdef BUSY_WAITING
int core;
for (core = 0; core < CONTEXT_THREADS_MAX; core++) {
plasma->barrier_in[core] = 0;
plasma->barrier_out[core] = 0;
}
#else
plasma->barrier_id = 0;
pthread_cond_init( &(plasma->barrier_synccond), NULL);
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

int PLASMA_Finalize ( )

PLASMA_Finalize - Finalize PLASMA.

Returns:
Return values:
PLASMA_SUCCESSsuccessful exit

Definition at line 293 of file control.c.

References plasma_context_struct::action, plasma_context_struct::action_condt, plasma_context_struct::action_mutex, PLASMA_ACT_FINALIZE, PLASMA_ACT_STAND_BY, plasma_barrier(), plasma_barrier_finalize(), plasma_context_remove(), plasma_context_self(), plasma_dynamic_sync, PLASMA_ERR_NOT_INITIALIZED, plasma_fatal_error(), PLASMA_SUCCESS, plasma_topology_finalize(), pthread_attr_destroy(), pthread_cond_broadcast(), pthread_join(), pthread_mutex_lock(), pthread_mutex_unlock(), pthread_self(), pthread_setconcurrency(), plasma_context_struct::quark, QUARK_Free(), plasma_context_struct::thread_attr, plasma_context_struct::thread_id, and plasma_context_struct::world_size.

{
int core;
int status;
void *exitcodep;
plasma = plasma_context_self();
if (plasma == NULL) {
plasma_fatal_error("PLASMA_Finalize()", "PLASMA not initialized");
}
/* Terminate the dynamic scheduler */
/* Free quark structures */
QUARK_Free(plasma->quark);
/* Set termination action */
/* Barrier and clear action */
plasma_barrier(plasma);
// Join threads
for (core = 1; core < plasma->world_size; core++) {
status = pthread_join(plasma->thread_id[core], &exitcodep);
if (status != 0) {
plasma_fatal_error("PLASMA_Finalize", "pthread_join() failed");
return status;
}
}
/* Destroy thread attributes */
status = pthread_attr_destroy(&plasma->thread_attr);
if (status != 0)
plasma_fatal_error("PLASMA_Finalize", "pthread_attr_destroy() failed");
/* Destroy topology */
status = plasma_context_remove(plasma, pthread_self());
if (status != PLASMA_SUCCESS) {
plasma_fatal_error("PLASMA_Finalize", "plasma_context_remove() failed");
return status;
}
/* Restore the concurency */
/* actually it's really bad, we shoulde set the concurrency only
* if it's not already done and restore it only we had change it */
}

Here is the call graph for this function:

Here is the caller graph for this function:

int PLASMA_Init ( int  cores)

PLASMA_Init - Initialize PLASMA.

Parameters:
[in]coresNumber of cores to use (threads to launch). If cores = 0, cores = PLASMA_NUM_THREADS if it is set, the system number of core otherwise.
Returns:
Return values:
PLASMA_SUCCESSsuccessful exit

Definition at line 153 of file control.c.

References PLASMA_Init_Affinity().

{
return PLASMA_Init_Affinity(cores, NULL);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int PLASMA_Init_Affinity ( int  cores,
int *  coresbind 
)

PLASMA_Init_Affinity - Initialize PLASMA.

Parameters:
[in]coresNumber of cores to use (threads to launch). If cores = 0, cores = PLASMA_NUM_THREADS if it is set, the system number of core otherwise.
[in]coresbindArray to specify where to bind each thread. Each thread i is binded to coresbind[hwloc(i)] if hwloc is provided, or to coresbind[i] otherwise. If coresbind = NULL, coresbind = PLASMA_AFF_THREADS if it is set, the identity function otherwise.
Returns:
Return values:
PLASMA_SUCCESSsuccessful exit

Definition at line 184 of file control.c.

References CONTEXT_THREADS_MAX, plasma_context_struct::group_size, plasma_barrier(), plasma_barrier_init(), plasma_context_create(), plasma_context_insert(), PLASMA_ERR_INTERNAL_LIMIT, PLASMA_ERR_NOT_FOUND, PLASMA_ERR_OUT_OF_RESOURCES, plasma_fatal_error(), plasma_get_affthreads(), plasma_get_numthreads(), plasma_get_numthreads_numa(), plasma_parallel_section(), plasma_setaffinity(), PLASMA_SUCCESS, plasma_topology_init(), plasma_warning(), pthread_attr_init(), pthread_attr_setscope(), pthread_create(), PTHREAD_SCOPE_SYSTEM, pthread_self(), pthread_setconcurrency(), plasma_context_struct::quark, QUARK_Setup(), plasma_context_struct::thread_attr, plasma_context_struct::thread_bind, plasma_context_struct::thread_id, plasma_context_struct::thread_rank, and plasma_context_struct::world_size.

{
int status;
int core;
/* Create context and insert in the context map */
if (plasma == NULL) {
plasma_fatal_error("PLASMA_Init", "plasma_context_create() failed");
}
status = plasma_context_insert(plasma, pthread_self());
if (status != PLASMA_SUCCESS) {
plasma_fatal_error("PLASMA_Init", "plasma_context_insert() failed");
}
/* Init number of cores and topology */
/* Set number of cores */
if ( cores < 1 ) {
if ( plasma->world_size == -1 ) {
plasma->world_size = 1;
plasma_warning("PLASMA_Init", "Could not find the number of cores: the thread number is set to 1");
}
}
else
plasma->world_size = cores;
if (plasma->world_size <= 0) {
plasma_fatal_error("PLASMA_Init", "failed to get system size");
}
/* Check if not more cores than the hard limit */
plasma_fatal_error("PLASMA_Init", "not supporting so many cores");
}
/* Get the size of each NUMA node */
while ( ((plasma->world_size)%(plasma->group_size)) != 0 )
(plasma->group_size)--;
/* Initialize barrier */
/* Initialize default thread attributes */
status = pthread_attr_init(&plasma->thread_attr);
if (status != 0) {
plasma_fatal_error("PLASMA_Init", "pthread_attr_init() failed");
return status;
}
/* Set scope to system */
if (status != 0) {
plasma_fatal_error("PLASMA_Init", "pthread_attr_setscope() failed");
return status;
}
/* Set concurrency */
if (status != 0) {
plasma_fatal_error("PLASMA_Init", "pthread_setconcurrency() failed");
return status;
}
/* Launch threads */
memset(plasma->thread_id, 0, CONTEXT_THREADS_MAX*sizeof(pthread_t));
if (coresbind != NULL) {
memcpy(plasma->thread_bind, coresbind, plasma->world_size*sizeof(int));
}
else {
}
/* Assign rank and thread ID for the master */
plasma->thread_rank[0] = 0;
plasma->thread_id[0] = pthread_self();
for (core = 1; core < plasma->world_size; core++) {
plasma->thread_rank[core] = core;
&plasma->thread_id[core],
&plasma->thread_attr,
(void*)plasma);
}
/* Set thread affinity for the master */
/* Initialize the dynamic scheduler */
plasma->quark = QUARK_Setup(plasma->world_size);
plasma_barrier(plasma);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void* plasma_parallel_section ( void *  plasma_ptr)

Main thread control

Definition at line 100 of file control.c.

References plasma_context_struct::action, plasma_context_struct::action_condt, plasma_context_struct::action_mutex, plasma_context_struct::parallel_func_ptr, PLASMA_ACT_DYNAMIC, PLASMA_ACT_FINALIZE, PLASMA_ACT_PARALLEL, PLASMA_ACT_STAND_BY, plasma_barrier(), plasma_fatal_error(), plasma_rank(), plasma_setaffinity(), pthread_cond_wait(), pthread_mutex_lock(), pthread_mutex_unlock(), plasma_context_struct::quark, QUARK_Worker_Loop(), and plasma_context_struct::thread_bind.

{
PLASMA_enum action;
/* Set thread affinity for the worker */
plasma_barrier(plasma);
while(1) {
while ((action = plasma->action) == PLASMA_ACT_STAND_BY)
plasma_barrier(plasma);
switch (action) {
plasma->parallel_func_ptr(plasma);
break;
QUARK_Worker_Loop(plasma->quark, plasma_rank(plasma));
break;
return NULL;
default:
plasma_fatal_error("plasma_parallel_section", "undefined action");
return NULL;
}
plasma_barrier(plasma);
}
return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function: