/** * * @file context.c * * @copyright 2009-2014 The University of Tennessee and The University of * Tennessee Research Foundation. All rights reserved. * @copyright 2012-2016 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, * Univ. Bordeaux. All rights reserved. * *** * * @brief Chameleon context management routines * * @version 1.0.0 * @author Jakub Kurzak * @author Mathieu Faverge * @author Cedric Castagnede * @date 2012-09-15 * *** * * @defgroup Options * @brief Group routines exposed to users to handle options * */ #include <stdlib.h> #if defined( _WIN32 ) || defined( _WIN64 ) #include "control/morsewinthread.h" #else #include <pthread.h> #endif #include "control/common.h" #include "control/auxiliary.h" #include "control/context.h" #include "chameleon/morse_runtime.h" #if !defined(CHAMELEON_SIMULATION) #include "coreblas.h" #endif /** * Global data */ /* master threads context lookup table */ static MORSE_context_t *morse_ctxt = NULL; /** * Create new context */ MORSE_context_t *morse_context_create() { MORSE_context_t *morse; if ( morse_ctxt != NULL ) { morse_error("morse_context_create", "a context is already existing\n"); return NULL; } morse = (MORSE_context_t*)malloc(sizeof(MORSE_context_t)); if (morse == NULL) { morse_error("morse_context_create", "malloc() failed"); return NULL; } /* These initializations are just in case the user disables autotuning and does not set nb and ib */ morse->nb = 128; morse->ib = 32; morse->rhblock = 4; morse->nworkers = 1; morse->ncudas = 0; morse->nthreads_per_worker= 1; morse->warnings_enabled = MORSE_TRUE; morse->autotuning_enabled = MORSE_TRUE; morse->parallel_enabled = MORSE_FALSE; morse->profiling_enabled = MORSE_FALSE; morse->progress_enabled = MORSE_FALSE; morse->householder = MORSE_FLAT_HOUSEHOLDER; morse->translation = MORSE_OUTOFPLACE; /* Initialize scheduler */ RUNTIME_context_create(morse); morse_ctxt = morse; return morse; } /** * Return context for a thread */ MORSE_context_t *morse_context_self() { return morse_ctxt; } /** * Clean the context */ int morse_context_destroy(){ RUNTIME_context_destroy(morse_ctxt); free(morse_ctxt); morse_ctxt = NULL; return MORSE_SUCCESS; } /** * * @ingroup Options * * MORSE_Enable - Enable MORSE feature. * ******************************************************************************* * * @param[in] option * Feature to be enabled: * @arg MORSE_WARNINGS printing of warning messages, * @arg MORSE_AUTOTUNING autotuning for tile size and inner block size. * @arg MORSE_PROFILING_MODE activate profiling of kernels * @arg MORSE_PROGRESS activate progress indicator * @arg MORSE_GEMM3M Use z/cgemm3m for complexe matrix-matrix products * ******************************************************************************* * * @return * \retval MORSE_SUCCESS successful exit * */ int MORSE_Enable(MORSE_enum option) { MORSE_context_t *morse; morse = morse_context_self(); if (morse == NULL) { morse_error("MORSE_Enable", "MORSE not initialized"); return MORSE_ERR_NOT_INITIALIZED; } switch (option) { case MORSE_WARNINGS: morse->warnings_enabled = MORSE_TRUE; break; case MORSE_AUTOTUNING: morse->autotuning_enabled = MORSE_TRUE; break; case MORSE_PROFILING_MODE: morse->profiling_enabled = MORSE_TRUE; break; case MORSE_PROGRESS: morse->progress_enabled = MORSE_TRUE; break; case MORSE_GEMM3M: #if defined(CBLAS_HAS_ZGEMM3M) && !defined(CHAMELEON_SIMULATION) set_coreblas_gemm3m_enabled(1); #else morse_error("MORSE_Enable", "cannot enable GEMM3M (not available in cblas)"); #endif break; /* case MORSE_PARALLEL: */ /* morse->parallel_enabled = MORSE_TRUE; */ /* break; */ default: morse_error("MORSE_Enable", "illegal parameter value"); return MORSE_ERR_ILLEGAL_VALUE; case MORSE_BOUND: break; } /* Enable at the lower level if required */ RUNTIME_enable( option ); return MORSE_SUCCESS; } /** * * @ingroup Options * * MORSE_Disable - Disable MORSE feature. * ******************************************************************************* * * @param[in] option * Feature to be disabled: * @arg MORSE_WARNINGS printing of warning messages, * @arg MORSE_AUTOTUNING autotuning for tile size and inner block size. * @arg MORSE_PROFILING_MODE deactivate profiling of kernels * @arg MORSE_PROGRESS deactivate progress indicator * @arg MORSE_GEMM3M Use z/cgemm3m for complexe matrix-matrix products * ******************************************************************************* * * @return * \retval MORSE_SUCCESS successful exit * */ int MORSE_Disable(MORSE_enum option) { MORSE_context_t *morse; morse = morse_context_self(); if (morse == NULL) { morse_error("MORSE_Disable", "MORSE not initialized"); return MORSE_ERR_NOT_INITIALIZED; } switch ( option ) { case MORSE_WARNINGS: morse->warnings_enabled = MORSE_FALSE; break; case MORSE_AUTOTUNING: morse->autotuning_enabled = MORSE_FALSE; break; case MORSE_PROFILING_MODE: morse->profiling_enabled = MORSE_FALSE; break; case MORSE_PROGRESS: morse->progress_enabled = MORSE_FALSE; break; case MORSE_GEMM3M: #if defined(CBLAS_HAS_ZGEMM3M) && !defined(CHAMELEON_SIMULATION) set_coreblas_gemm3m_enabled(0); #endif break; case MORSE_PARALLEL_MODE: morse->parallel_enabled = MORSE_FALSE; break; default: morse_error("MORSE_Disable", "illegal parameter value"); return MORSE_ERR_ILLEGAL_VALUE; } /* Disable at the lower level if required */ RUNTIME_disable( option ); return MORSE_SUCCESS; } /** * * @ingroup Options * * MORSE_Set - Set MORSE parameter. * ******************************************************************************* * * @param[in] param * Feature to be enabled: * @arg MORSE_TILE_SIZE: size matrix tile, * @arg MORSE_INNER_BLOCK_SIZE: size of tile inner block, * * @param[in] value * Value of the parameter. * ******************************************************************************* * * @return * \retval MORSE_SUCCESS successful exit * */ int MORSE_Set(MORSE_enum param, int value) { MORSE_context_t *morse; morse = morse_context_self(); if (morse == NULL) { morse_error("MORSE_Set", "MORSE not initialized"); return MORSE_ERR_NOT_INITIALIZED; } switch (param) { case MORSE_TILE_SIZE: if (value <= 0) { morse_error("MORSE_Set", "negative tile size"); return MORSE_ERR_ILLEGAL_VALUE; } morse->nb = value; if ( morse->autotuning_enabled ) { morse->autotuning_enabled = MORSE_FALSE; morse_warning("MORSE_Set", "autotuning has been automatically disable\n"); } /* Limit ib to nb */ morse->ib = chameleon_min( morse->nb, morse->ib ); break; case MORSE_INNER_BLOCK_SIZE: if (value <= 0) { morse_error("MORSE_Set", "negative inner block size"); return MORSE_ERR_ILLEGAL_VALUE; } if (value > morse->nb) { morse_error("MORSE_Set", "inner block larger than tile"); return MORSE_ERR_ILLEGAL_VALUE; } /* if (morse->nb % value != 0) { */ /* morse_error("MORSE_Set", "inner block does not divide tile"); */ /* return MORSE_ERR_ILLEGAL_VALUE; */ /* } */ morse->ib = value; if ( morse->autotuning_enabled ) { morse->autotuning_enabled = MORSE_FALSE; morse_warning("MORSE_Set", "autotuning has been automatically disable\n"); } break; case MORSE_HOUSEHOLDER_MODE: if (value != MORSE_FLAT_HOUSEHOLDER && value != MORSE_TREE_HOUSEHOLDER) { morse_error("MORSE_Set", "illegal value of MORSE_HOUSEHOLDER_MODE"); return MORSE_ERR_ILLEGAL_VALUE; } morse->householder = value; break; case MORSE_HOUSEHOLDER_SIZE: if (value <= 0) { morse_error("MORSE_Set", "negative householder size"); return MORSE_ERR_ILLEGAL_VALUE; } morse->rhblock = value; break; case MORSE_TRANSLATION_MODE: if (value != MORSE_INPLACE && value != MORSE_OUTOFPLACE) { morse_error("MORSE_Set", "illegal value of MORSE_TRANSLATION_MODE"); return MORSE_ERR_ILLEGAL_VALUE; } morse->translation = value; break; default: morse_error("MORSE_Set", "unknown parameter"); return MORSE_ERR_ILLEGAL_VALUE; } return MORSE_SUCCESS; } /** * * @ingroup Options * * MORSE_Get - Get value of MORSE parameter. * ******************************************************************************* * * @param[in] param * Feature to be enabled: * @arg MORSE_TILE_SIZE: size matrix tile, * @arg MORSE_INNER_BLOCK_SIZE: size of tile inner block, * * @param[out] value * Value of the parameter. * ******************************************************************************* * * @return * \retval MORSE_SUCCESS successful exit * */ int MORSE_Get(MORSE_enum param, int *value) { MORSE_context_t *morse; morse = morse_context_self(); if (morse == NULL) { morse_error("MORSE_Get", "MORSE not initialized"); return MORSE_ERR_NOT_INITIALIZED; } switch (param) { case MORSE_TILE_SIZE: *value = morse->nb; return MORSE_SUCCESS; case MORSE_INNER_BLOCK_SIZE: *value = morse->ib; return MORSE_SUCCESS; case MORSE_HOUSEHOLDER_MODE: *value = morse->householder; return MORSE_SUCCESS; case MORSE_HOUSEHOLDER_SIZE: *value = morse->rhblock; return MORSE_SUCCESS; case MORSE_TRANSLATION_MODE: *value = morse->translation; return MORSE_SUCCESS; default: morse_error("MORSE_Get", "unknown parameter"); return MORSE_ERR_ILLEGAL_VALUE; } return MORSE_SUCCESS; }