CHAMELEON 1.4.0
Loading...
Searching...
No Matches
descriptor_helpers.c
Go to the documentation of this file.
1
33#include "control/common.h"
34#include <stdlib.h>
35#include <stdio.h>
36#include <assert.h>
37#include <string.h>
38#include "control/descriptor.h"
39#include "chameleon/runtime.h"
40
57int chameleon_getrankof_2d( const CHAM_desc_t *A, int m, int n )
58{
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));
62}
63
80int chameleon_getrankof_2d_diag( const CHAM_desc_t *A, int m, int n )
81{
82 int mm = m + A->i / A->mb;
83 (void)n;
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));
85}
86
103int chameleon_getrankof_ipiv_2d_row( const CHAM_ipiv_t *IPIV, int m, int n )
104{
105 int Q = IPIV->NP / IPIV->P;
106 (void)n;
107 return ( m % IPIV->P ) * Q;
108}
109
126int chameleon_getrankof_ipiv_2d_col( const CHAM_ipiv_t *IPIV, int m, int n )
127{
128 int Q = IPIV->NP / IPIV->P;
129 (void)m;
130 return n % Q;
131}
132
149int chameleon_getrankof_ipiv_2d_diag( const CHAM_ipiv_t *IPIV, int m, int n )
150{
151 (void)n;
152 int Q = IPIV->NP / IPIV->P;
153 return (m % IPIV->P) * Q + (m % Q);
154}
155
169int chameleon_involved_in_panelk_2dbc( const CHAM_desc_t *A, int k ) {
170 int myrank = A->myrank;
171 return ( myrank % chameleon_desc_datadist_get_iparam(A,1) == k % chameleon_desc_datadist_get_iparam(A,1) );
172}
173
190int chameleon_p_involved_in_panelk_2dbc( const CHAM_desc_t *A, int k, int p ) {
191 return ( p % chameleon_desc_datadist_get_iparam(A,1) == k % chameleon_desc_datadist_get_iparam(A,1) );
192}
193
211 int k,
212 int n,
213 void *ws_reduce )
214{
215#if defined (CHAMELEON_USE_MPI)
216 CHAM_reduce_t *reduce = (CHAM_reduce_t*) ws_reduce;
217 int *proc_involved = reduce->proc_involved;
218 int b, rank, np;
219
220 np = 0;
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;
225 np ++;
226 if ( rank == A->myrank ) {
227 reduce->involved = 1;
228 }
229 }
230 reduce->proc_involved = proc_involved;
231 reduce->np_involved = np;
232#else
233 (void)A;
234 (void)k;
235 (void)n;
236 (void)ws_reduce;
237#endif
238}
239
257 int m,
258 int k,
259 void *ws_reduce )
260{
261#if defined (CHAMELEON_USE_MPI)
262 CHAM_reduce_t *reduce = (CHAM_reduce_t*) ws_reduce;
263 int *proc_involved = reduce->proc_involved;
264 int b, rank, np;
265
266 np = 0;
267 reduce->involved = 0;
268 for ( b = k; (b < A->nt) && ((b-k) < chameleon_desc_datadist_get_iparam(A, 1)); b ++ ) {
269 rank = chameleon_getrankof_2d( A, m, b );
270 proc_involved[ b-k ] = rank;
271 np ++;
272 if ( rank == A->myrank ) {
273 reduce->involved = 1;
274 }
275 }
276 reduce->proc_involved = proc_involved;
277 reduce->np_involved = np;
278#else
279 (void)A;
280 (void)k;
281 (void)m;
282 (void)ws_reduce;
283#endif
284}
285
303int chameleon_getrankof_custom_init( custom_dist_t **custom_dist,
304 const char *dist_file )
305{
306 custom_dist_t *result;
307 FILE *f;
308 int i, j, rc;
309 int np, dist_m, dist_n;
310
311 *custom_dist = NULL;
312
313 /* Get number of processes to check for correctness */
314 np = CHAMELEON_Comm_size();
315
316 /* Allocate memory */
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;
321 }
322
323 result->dist_file = dist_file;
324 f = fopen( result->dist_file , "r" );
325 if ( f == NULL ) {
326 char message[300];
327 snprintf( message, 300, "could not open file '%s'", dist_file );
328 chameleon_error( "chameleon_getrankof_custom_init", message );
329 free( result );
330 return CHAMELEON_ERR_ILLEGAL_VALUE;
331 }
332
333 rc = fscanf( f, "%d %d", &dist_m, &dist_n );
334 if ( rc < 2 ) {
335 char message[300];
336 snprintf( message, 300, "could not read m and n in file '%s'", dist_file );
337 chameleon_error( "chameleon_getrankof_custom_init", message );
338 free( result );
339 fclose( f );
340 return CHAMELEON_ERR_ILLEGAL_VALUE;
341 }
342
343 if ( (dist_m <= 0 ) || (dist_n <= 0) ) {
344 char message[300];
345 snprintf( message, 300, "Incorrect values for dist_m(%d) and/or dist_n(%d)", dist_m, dist_n );
346 chameleon_error( "chameleon_getrankof_custom_init", message );
347 free( result );
348 fclose( f );
349 return CHAMELEON_ERR_ILLEGAL_VALUE;
350 }
351
352 result->dist_m = dist_m;
353 result->dist_n = dist_n;
354
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" );
358 free( result );
359 fclose( f );
360 return CHAMELEON_ERR_OUT_OF_RESOURCES;
361 }
362
363 for(i = 0; i < dist_m; i++) {
364 for(j = 0; j < dist_n; j++) {
365 int rank;
366
367 rc = fscanf( f, "%d", &rank );
368 if ( rc < 1 ) {
369 char message[300];
370 snprintf(message, 300, "file '%s': could not read value at position (%d, %d)", dist_file, i, j );
371 chameleon_error( "chameleon_getrankof_custom_init", message );
372 free( result->blocks_dist );
373 free( result );
374 fclose( f );
375 return CHAMELEON_ERR_ILLEGAL_VALUE;
376 }
377
378 if ( (rank < 0 ) || (rank >= np) )
379 {
380 char message[300];
381 snprintf( message, 300, "file '%s': value %d at position (%d, %d) is invalid with %d processes",
382 dist_file, rank, i, j, np );
383 chameleon_error( "chameleon_getrankof_custom_init", message );
384 free( result->blocks_dist );
385 free( result );
386 fclose( f );
387 return CHAMELEON_ERR_ILLEGAL_VALUE;
388 }
389
390 result->blocks_dist[j * dist_m + i] = rank;
391 }
392 }
393 fclose(f);
394
395 *custom_dist = result;
396 return CHAMELEON_SUCCESS;
397}
398
408int
410{
411 if ((dist == NULL) || (*dist == NULL)) {
412 chameleon_error("chameleon_getrankof_custom_destroy", "attempting to destroy a NULL descriptor");
413 return CHAMELEON_ERR_UNALLOCATED;
414 }
415
416 free((*dist)->blocks_dist);
417 free(*dist);
418 *dist = NULL;
419 return CHAMELEON_SUCCESS;
420}
421
432int chameleon_getrankof_custom( const CHAM_desc_t *desc, int m, int n )
433{
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)];
436}
437
456void* chameleon_getaddr_ccrb( const CHAM_desc_t *A, int m, int n )
457{
458 size_t mm = m + A->i / A->mb;
459 size_t nn = n + A->j / A->nb;
460 size_t eltsize = CHAMELEON_Element_Size(A->dtyp);
461 size_t offset = 0;
462
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);
467#endif
468
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 );
472 else
473 offset = A->A12 + ((size_t)(A->mb * (A->lln%A->nb)) * mm );
474 }
475 else {
476 if (nn < (size_t)(A->lln1))
477 offset = A->A21 + ((size_t)((A->llm%A->mb) * A->nb) * nn );
478 else
479 offset = A->A22;
480 }
481
482 return (void*)((intptr_t)A->mat + (offset*eltsize) );
483}
484
503void *chameleon_getaddr_cm( const CHAM_desc_t *A, int m, int n )
504{
505 size_t eltsize = CHAMELEON_Element_Size(A->dtyp);
506 size_t offset = chameleon_getaddr_cm_offset( A, m, n, A->llm );
507
508 return (void*)((intptr_t)A->mat + (offset*eltsize) );
509}
510
529void *chameleon_getaddr_diag( const CHAM_desc_t *A, int m, int n )
530{
531 (void)n;
532 return chameleon_getaddr_ccrb( A, m, 0 );
533}
534
554void *chameleon_getaddr_null( const CHAM_desc_t *A, int m, int n )
555{
556 (void)A; (void)m; (void)n;
557 return NULL;
558}
559
579int chameleon_getblkldd_ccrb( const CHAM_desc_t *A, int m )
580{
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;
583}
584
604int chameleon_getblkldd_cm( const CHAM_desc_t *A, int m )
605{
606 (void)m;
607 return A->llm;
608}
void chameleon_error(const char *func_name, const char *msg_text)
Definition auxiliary.c:101
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)
Definition auxiliary.c:212
int CHAMELEON_Comm_size()
Definition control.c:337