33#include "control/common.h"
38#include "control/descriptor.h"
39#include "chameleon/runtime.h"
59 int mm = m + A->i / A->mb;
60 int nn = n + A->j / A->nb;
61 return (mm % chameleon_desc_datadist_get_iparam(A,0)) * chameleon_desc_datadist_get_iparam(A,1) + (nn % chameleon_desc_datadist_get_iparam(A,1));
82 int mm = m + A->i / A->mb;
84 return (mm % chameleon_desc_datadist_get_iparam(A,0)) * chameleon_desc_datadist_get_iparam(A,1) + (mm % chameleon_desc_datadist_get_iparam(A,1));
105 int Q = IPIV->NP / IPIV->P;
107 return ( m % IPIV->P ) * Q;
128 int Q = IPIV->NP / IPIV->P;
152 int Q = IPIV->NP / IPIV->P;
153 return (m % IPIV->P) * Q + (m % Q);
170 int myrank = A->myrank;
171 return ( myrank % chameleon_desc_datadist_get_iparam(A,1) == k % chameleon_desc_datadist_get_iparam(A,1) );
191 return ( p % chameleon_desc_datadist_get_iparam(A,1) == k % chameleon_desc_datadist_get_iparam(A,1) );
215#if defined (CHAMELEON_USE_MPI)
216 CHAM_reduce_t *reduce = (CHAM_reduce_t*) ws_reduce;
217 int *proc_involved = reduce->proc_involved;
221 reduce->involved = 0;
222 for ( b = k; (b < A->mt) && ((b-k) < chameleon_desc_datadist_get_iparam(A, 0)); b ++ ) {
223 rank = A->get_rankof( A, b, n );
224 proc_involved[ b-k ] = rank;
226 if ( rank == A->myrank ) {
227 reduce->involved = 1;
230 reduce->proc_involved = proc_involved;
231 reduce->np_involved = np;
261#if defined (CHAMELEON_USE_MPI)
262 CHAM_reduce_t *reduce = (CHAM_reduce_t*) ws_reduce;
263 int *proc_involved = reduce->proc_involved;
267 reduce->involved = 0;
268 for ( b = k; (b < A->nt) && ((b-k) < chameleon_desc_datadist_get_iparam(A, 1)); b ++ ) {
270 proc_involved[ b-k ] = rank;
272 if ( rank == A->myrank ) {
273 reduce->involved = 1;
276 reduce->proc_involved = proc_involved;
277 reduce->np_involved = np;
304 const char *dist_file )
306 custom_dist_t *result;
309 int np, dist_m, dist_n;
317 result = (custom_dist_t*) malloc(
sizeof(custom_dist_t) );
318 if ( result == NULL ) {
319 chameleon_error(
"chameleon_getrankof_custom_init",
"malloc() failed" );
320 return CHAMELEON_ERR_OUT_OF_RESOURCES;
323 result->dist_file = dist_file;
324 f = fopen( result->dist_file ,
"r" );
327 snprintf( message, 300,
"could not open file '%s'", dist_file );
330 return CHAMELEON_ERR_ILLEGAL_VALUE;
333 rc = fscanf( f,
"%d %d", &dist_m, &dist_n );
336 snprintf( message, 300,
"could not read m and n in file '%s'", dist_file );
340 return CHAMELEON_ERR_ILLEGAL_VALUE;
343 if ( (dist_m <= 0 ) || (dist_n <= 0) ) {
345 snprintf( message, 300,
"Incorrect values for dist_m(%d) and/or dist_n(%d)", dist_m, dist_n );
349 return CHAMELEON_ERR_ILLEGAL_VALUE;
352 result->dist_m = dist_m;
353 result->dist_n = dist_n;
355 result->blocks_dist = (
int*) malloc(
sizeof(
int) * dist_m * dist_n );
356 if ( result->blocks_dist == NULL ) {
357 chameleon_error(
"chameleon_getrankof_custom_init",
"could not allocate blocks table" );
360 return CHAMELEON_ERR_OUT_OF_RESOURCES;
363 for(i = 0; i < dist_m; i++) {
364 for(j = 0; j < dist_n; j++) {
367 rc = fscanf( f,
"%d", &rank );
370 snprintf(message, 300,
"file '%s': could not read value at position (%d, %d)", dist_file, i, j );
372 free( result->blocks_dist );
375 return CHAMELEON_ERR_ILLEGAL_VALUE;
378 if ( (rank < 0 ) || (rank >= np) )
381 snprintf( message, 300,
"file '%s': value %d at position (%d, %d) is invalid with %d processes",
382 dist_file, rank, i, j, np );
384 free( result->blocks_dist );
387 return CHAMELEON_ERR_ILLEGAL_VALUE;
390 result->blocks_dist[j * dist_m + i] = rank;
395 *custom_dist = result;
396 return CHAMELEON_SUCCESS;
411 if ((dist == NULL) || (*dist == NULL)) {
412 chameleon_error(
"chameleon_getrankof_custom_destroy",
"attempting to destroy a NULL descriptor");
413 return CHAMELEON_ERR_UNALLOCATED;
416 free((*dist)->blocks_dist);
419 return CHAMELEON_SUCCESS;
434 custom_dist_t *dist = desc->get_rankof_init_arg;
435 return dist->blocks_dist[(n % dist->dist_n) * dist->dist_m + (m % dist->dist_m)];
458 size_t mm = m + A->i / A->mb;
459 size_t nn = n + A->j / A->nb;
463#if defined(CHAMELEON_USE_MPI)
464 assert( A->myrank == A->get_rankof( A, mm, nn ) );
465 mm = mm / chameleon_desc_datadist_get_iparam(A, 0);
466 nn = nn / chameleon_desc_datadist_get_iparam(A, 1);
469 if (mm < (
size_t)(A->llm1)) {
470 if (nn < (
size_t)(A->lln1))
471 offset = (size_t)(A->bsiz) * (mm + (size_t)(A->llm1) * nn );
473 offset = A->A12 + ((size_t)(A->mb * (A->lln%A->nb)) * mm );
476 if (nn < (
size_t)(A->lln1))
477 offset = A->A21 + ((size_t)((A->llm%A->mb) * A->nb) * nn );
482 return (
void*)((intptr_t)A->mat + (offset*eltsize) );
506 size_t offset = chameleon_getaddr_cm_offset( A, m, n, A->llm );
508 return (
void*)((intptr_t)A->mat + (offset*eltsize) );
556 (void)A; (void)m; (void)n;
581 int mm = m + A->i / A->mb;
582 return ( ((mm+1) == A->lmt) && ((A->lm % A->mb) != 0)) ? A->lm % A->mb : A->mb;
void chameleon_error(const char *func_name, const char *msg_text)
int chameleon_getrankof_2d(const CHAM_desc_t *A, int m, int n)
Return the rank of the tile A( m, n ) in a classic 2D Block Cyclic distribution PxQ.
void chameleon_get_proc_involved_in_panelk_2dbc(const CHAM_desc_t *A, int k, int n, void *ws_reduce)
Test if the current MPI process is involved in the panel k for 2DBC distributions.
int chameleon_getblkldd_ccrb(const CHAM_desc_t *A, int m)
Return the leading dimension of the tile A( m, m ) stored in a tiled storage.
void * chameleon_getaddr_diag(const CHAM_desc_t *A, int m, int n)
Return the address of the tile A( m, m ) in a tile storage.
int chameleon_getrankof_custom(const CHAM_desc_t *desc, int m, int n)
Internal function to return MPI rank of block (m,n) in distribution custom from dist file.
int chameleon_getrankof_custom_init(custom_dist_t **custom_dist, const char *dist_file)
Initializes a custom distribution based on an external file.
int chameleon_p_involved_in_panelk_2dbc(const CHAM_desc_t *A, int k, int p)
Test if the MPI process p is involved in the panel k for 2DBC distributions.
int chameleon_getrankof_2d_diag(const CHAM_desc_t *A, int m, int n)
Return the rank associated to the diagonal tile ( m, m ) of a classic 2D Block Cyclic distribution Px...
int chameleon_getrankof_ipiv_2d_row(const CHAM_ipiv_t *IPIV, int m, int n)
Return the rank of the process responsible for the permutation of the tile (m, n) in a classic 2D Blo...
void chameleon_get_proc_involved_in_rowpanelk_2dbc(const CHAM_desc_t *A, int m, int k, void *ws_reduce)
Test if the current MPI process is involved in the panel k for 2DBC distributions.
int chameleon_getrankof_ipiv_2d_col(const CHAM_ipiv_t *IPIV, int m, int n)
Return the rank of the process responsible for the column permutation of the tile (m,...
int chameleon_getrankof_custom_destroy(custom_dist_t **dist)
Destroys a custom distribution based on an external file.
int chameleon_getrankof_ipiv_2d_diag(const CHAM_ipiv_t *IPIV, int m, int n)
Return the rank of the process responsible for the permutation of the tile (m, n) when used for getrf...
void * chameleon_getaddr_ccrb(const CHAM_desc_t *A, int m, int n)
Return the address of the tile A( m, n ) in a tile storage.
void * chameleon_getaddr_null(const CHAM_desc_t *A, int m, int n)
Return the address of the tile A( m, m ) in a dynamic storage.
int chameleon_getblkldd_cm(const CHAM_desc_t *A, int m)
Return the leading dimension of the tile A( m, m ) stored in a column major storage.
int chameleon_involved_in_panelk_2dbc(const CHAM_desc_t *A, int k)
Test if the current MPI process is involved in the panel k for 2DBC distributions.
void * chameleon_getaddr_cm(const CHAM_desc_t *A, int m, int n)
Return the address of the tile A( m, n ) in a column major storage.
ssize_t CHAMELEON_Element_Size(cham_flttype_t type)
int CHAMELEON_Comm_size()