Commit 95f9a9a6 authored by iker_martin's avatar iker_martin
Browse files

First commit

parent 8dc4bd2b
This diff is collapsed.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ScalarVectors.h"
int CreateInts (int **vint, int num)
{
if ((*vint = (int *) malloc (sizeof(int)*num)) == NULL)
{ printf ("Memory Error (CreateInts(%d))\n", num); exit (1); }
}
int InitInts (int *vint, int n, int frst, int incr)
{
int i, *p1 = vint, num = frst;
for (i=0; i<n; i++)
{ *(p1++) = num; num += incr; }
}
int CopyInts (int *src, int *dst, int n)
{ memmove (dst, src, sizeof(int) * n); }
int CopyShiftInts (int *src, int *dst, int n, int shft)
{
int i, *p1 = src, *p2 = dst;
for (i=0; i<n; i++)
*(p2++) = *(p1++) + shft;
}
int TransformLengthtoHeader (int *vec, int n)
{
int i, *pi = vec;
for (i=0; i<n; i++) { *(pi+1) += *pi; pi++; }
}
int TransformHeadertoLength (int *vec, int n)
{
int i, *pi = &(vec[n]);
for (i=n; i>=1; i--) { *pi -= *(pi-1); pi--; }
}
void GetIntFromString (char *string, int *pnum, int numC, int shft)
{
int j = 0, num = 0, neg = 0;
char *pchar = string;
while ((j < numC) && ((*pchar < '0') || (*pchar > '9')) &&
(*pchar != '+') && (*pchar != '-')) { j++; pchar++; }
if (j < numC)
{
if ((*pchar == '+') || (*pchar == '-'))
{ neg = (*pchar == '-'); j++; pchar++; }
while ((j < numC) && (*pchar >= '0') && (*pchar <= '9'))
{ num = num * 10 + (*pchar - 48); j++; pchar++; }
}
if (neg) num = -num;
*pnum = num + shft;
}
void GetIntsFromString (char *string, int *vec, int numN, int numC, int shft)
{
int i, *pint = vec;
char *pchar = string;
for (i=0; i<numN; i++)
{ GetIntFromString (pchar, (pint++), numC, shft); pchar += numC; }
}
void GetFormatsFromString (char *string, int *vec, int numN, int numC)
{
int i, k = 0;
int *pint = vec;
char *pchar = string, *pch = NULL, c = ' ', c2;
for (i=0; i<numN; i++)
{
pch = pchar;
while (*pch == ' ') pch++;
sscanf (pch, "(%i%c", pint, &c);
if ((c == 'P') || (c == 'p'))
{
sscanf (pch, "(%i%c%i%c%i.%i)", &k, &c2, pint, &c, pint+1, pint+2);
pint += 3;
}
else if ((c == 'E') || (c == 'e') || (c == 'D') || (c == 'd') ||
(c == 'F') || (c == 'f') || (c == 'G') || (c == 'g'))
{
sscanf (pch, "(%i%c%i.%i)", pint, &c, pint+1, pint+2);
pint += 3;
}
else
{ sscanf (pch, "(%i%c%i)", pint, &c, pint+1); pint += 2; }
pchar += numC;
}
}
int PrintInts (int *vint, int num)
{
int i, *pi = vint;
for (i=0; i<num; i++) printf ("%d ", *(pi++));
printf ("\n");
}
int RemoveInts (int **vint)
{ free (*vint); *vint = NULL; }
int CreateDoubles (double **vdouble, int num)
{
if ((*vdouble = (double *) malloc (sizeof(double)*num)) == NULL)
{ printf ("Memory Error (CreateDoubles(%d))\n", num); exit (1); }
}
int InitDoubles (double *vdouble, int n, double frst, double incr)
{
int i;
double *p1 = vdouble, num = frst;
for (i=0; i<n; i++)
{ *(p1++) = num; num += incr; }
}
void GetDoubleFromString (char *string, double *pdbl, int numC)
{
int j, k, exp, neg;
double num, frac;
char *pchar = string;
j = 0; exp = 0; neg = 0; num = 0.0; frac = 1.0;
while ((j < numC) && ((*pchar < '0') || (*pchar > '9')) &&
(*pchar != '+') && (*pchar != '-') && (*pchar != '.')) { j++; pchar++; }
if (j < numC)
{
if ((*pchar == '+') || (*pchar == '-'))
{ neg = (*pchar == '-'); j++; pchar++; }
if (j < numC)
{
if (*pchar != '.')
while ((j < numC) && (*pchar >= '0') && (*pchar <= '9'))
{ num = num * 10 + (*pchar - 48); j++; pchar++; }
if (j < numC)
{
if (*pchar == '.')
{
j++; pchar++;
while ((j < numC) && (*pchar >= '0') && (*pchar <= '9'))
{ frac /= 10; num += (*pchar-48) * frac; j++; pchar++; }
}
if (neg) num = -num;
if (j < numC)
{
if ((*pchar == 'e') || (*pchar == 'E') || (*pchar == 'd') || (*pchar == 'D'))
{
neg = 0; j++; pchar++;
if (j < numC)
{
if ((*pchar == '+') || (*pchar == '-'))
{ neg = (*pchar == '-'); j++; pchar++; }
if (j < numC)
{
while ((j < numC) && (*pchar >= '0') &&
(*pchar <= '9'))
{ exp = exp*10 + (*pchar-48); j++; pchar++; }
if (neg) exp = -exp;
for (k=0; k<exp; k++) num *= 10;
for (k=0; k>exp; k--) num /= 10;
}
}
}
}
}
else
if (neg) num = -num;
}
}
*pdbl = num;
}
void GetDoublesFromString (char *string, double *vec, int numN, int numC)
{
int i;
double *paux = vec;
char *pchar = string;
for (i=0; i<numN; i++)
{ GetDoubleFromString (pchar, (paux++), numC); pchar += numC; }
}
int PrintDoubles (double *vdouble, int num)
{
int i;
double *pd = vdouble;
for (i=0; i<num; i++) printf ("%e ", *(pd++));
printf ("\n");
}
int RemoveDoubles (double **vdouble)
{ free (*vdouble); *vdouble = NULL; }
#ifndef ScalarVector
#define ScalarVector 1
#include <stdio.h>
extern int CreateInts (int **vint, int num);
extern int InitInts (int *vint, int n, int frst, int incr);
extern int CopyInts (int *src, int *dst, int n);
extern int CopyShiftInts (int *src, int *dst, int n, int shft);
extern int TransformLengthtoHeader (int *vec, int n);
extern int TransformHeadertoLength (int *vec, int n);
extern void GetIntFromString (char *string, int *pnum, int numC, int shft);
extern void GetIntsFromString (char *string, int *vec, int numN, int numC, int shft);
extern void GetFormatsFromString (char *string, int *vec, int numN, int numC);
extern int PrintInts (int *vint, int num);
extern int RemoveInts (int **vint);
extern int CreateDoubles (double **vdouble, int num);
extern int InitDoubles (double *vdouble, int n, double frst, double incr);
extern void GetDoubleFromString (char *string, double *pdbl, int numC);
extern void GetDoublesFromString (char *string, double *vec, int numN, int numC);
extern int PrintDoubles (double *vdouble, int num);
extern int RemoveDoubles (double **vdouble);
#endif
#include <stdio.h>
#include <stdlib.h>
#include "ScalarVectors.h"
#include "SparseMatrices.h"
#define length1 82
#define length2 82
FILE *OpenFile (char *name, char *attr)
{
FILE *fich;
if ((fich = fopen (name, attr)) == NULL)
{ printf ("File %s not exists \n", name); exit(1); }
return fich;
}
void ReadStringFile (FILE *file, char *string, int length)
{
char *s = NULL;
if ((s = fgets (string, length, file)) == NULL)
{ printf ("Error en lectura \n"); exit (1); }
}
int CreateSparseMatrix (ptr_SparseMatrix spr, int numR, int numC, int numE,
int msr)
{
spr->dim1 = numR; spr->dim2 = numC;
CreateInts (&(spr->vptr), numE+numR+1);
*(spr->vptr) = ((msr)? (numR+1): 0);
spr->vpos = spr->vptr + ((msr)? 0: (numR+1));
CreateDoubles (&(spr->vval), numE+(numR+1)*msr);
}
int CreateSparseMatrixVptr (ptr_SparseMatrix spr, int numR, int numC,
int msr)
{
spr->dim1 = numR; spr->dim2 = numC;
CreateInts (&(spr->vptr), numR+1);
*(spr->vptr) = ((msr)? (numR+1): 0);
return 0;
}
int CreateSparseMatrixValues (ptr_SparseMatrix spr, int numR, int numC, int numE,
int msr)
{
CreateInts (&(spr->vpos), numE+(numR+1)*msr);
CreateDoubles (&(spr->vval), numE+(numR+1)*msr);
return 0;
}
int PrintSparseMatrix (SparseMatrix spr, int CorF)
{
int i, j;
if (spr.vptr == spr.vpos)
{
printf ("Diagonals : \n ");
for (i=0; i<spr.dim1; i++) printf ("%f ", spr.vval[i]); printf ("\n");
}
printf ("Pointers: \n ");
if (spr.dim1 > 0)
for (i=0; i<spr.dim1; i++) printf ("%d ", spr.vptr[i]); printf ("\n");
printf ("Values: \n");
for (i=0; i<spr.dim1; i++)
{ printf (" Row %d --> ", i+CorF);
for (j=(spr.vptr[i]-CorF); j<(spr.vptr[i+1]-CorF); j++)
printf ("(%d,%f) ", spr.vpos[j], spr.vval[j]);
printf ("\n"); }
printf ("\n");
}
int RemoveSparseMatrix (ptr_SparseMatrix spr)
{
spr->dim1 = -1; spr->dim2 = -1;
RemoveInts (&(spr->vptr));
RemoveDoubles (&(spr->vval));
}
int RemoveSparseMatrix2 (ptr_SparseMatrix spr)
{
spr->dim1 = -1; spr->dim2 = -1;
RemoveInts (&(spr->vptr));
RemoveInts (&(spr->vpos));
RemoveDoubles (&(spr->vval));
return 0;
}
int ProdSparseMatrixVector (SparseMatrix spr, double *vec, double *res)
{
int i, j;
double aux;
for (i=0; i<spr.dim1; i++)
{
aux = 0.0;
for (j=spr.vptr[i]; j<spr.vptr[i+1]; j++) {
aux += spr.vval[j] * vec[spr.vpos[j]];
}
res[i] = aux;
}
}
int DesymmetrizeSparseMatrices (SparseMatrix src, ptr_SparseMatrix dst)
{
int i, j, row, col, pos1, pos2;
int n = src.dim1, nnz = 0;
int *sizes = NULL;
CreateInts (&sizes, n);
InitInts (sizes, n, 0, 0);
for (i=0; i<n; i++) {
for (j=src.vptr[i]; j<src.vptr[i+1]; j++) {
sizes[i]++; nnz++;
if (src.vpos[j] != i) {
sizes[src.vpos[j]]++; nnz++;
}
}
}
CreateSparseMatrix (dst, n, n, nnz, 0);
CopyInts (sizes, (dst->vptr)+1, n);
dst->vptr[0] = 0; TransformLengthtoHeader (dst->vptr, n);
CopyInts (dst->vptr, sizes, n);
for (i=0; i<n; i++) {
for (j=src.vptr[i]; j<src.vptr[i+1]; j++) {
row = i; pos1 = sizes[row];
dst->vpos[pos1] = src.vpos[j];
dst->vval[pos1] = src.vval[j];
sizes[row]++;
if (src.vpos[j] != i) {
col = src.vpos[j]; pos2 = sizes[col];
dst->vpos[pos2] = row;
dst->vval[pos2] = src.vval[j];
sizes[col]++;
}
}
}
RemoveInts (&sizes);
}
int ProdSymSparseMatrixVector (SparseMatrix spr, double *vec, double *res)
{
int i, j, k;
double aux, val;
for (i=0; i<spr.dim1; i++) res[i] = 0.0;
for (i=0; i<spr.dim1; i++)
{
aux = 0.0;
for (j=spr.vptr[i]; j<spr.vptr[i+1]; j++) {
k = spr.vpos[j]; val = spr.vval[j];
aux += val * vec[k];
if (k != i) res[k] += (val * vec[i]);
}
res[i] += aux;
}
}
void CreateSparseMatrixHB (char *nameFile, ptr_SparseMatrix spr, int FtoC)
{
FILE *file;
char string[length1], *s = NULL;
int i, j, k = 0, shft = (FtoC)?-1:0;
int *vptr = NULL, *vpos = NULL;
double *vval = NULL;
int lines[5], dim[4], formats[10];
file = OpenFile (nameFile, "r");
ReadStringFile (file, string, length1);
ReadStringFile (file, string, length1);
GetIntsFromString (string, lines, 5, 14, 0);
ReadStringFile (file, string, length1);
GetIntsFromString ((string+14), dim, 4, 14, 0);
CreateSparseMatrix (spr, dim[0], dim[1], dim[2], 0);
vptr = spr->vptr; vpos = spr->vpos; vval = spr->vval;
ReadStringFile (file, string, length1);
GetFormatsFromString (string, formats, 2, 16);
GetFormatsFromString ((string+32), (formats+4), 1+(lines[4] > 0), 20);
if (lines[4] > 0) ReadStringFile (file, string, length1);
j = 0;
for (i = 0; i < lines[1]; i++)
{
ReadStringFile (file, string, length2);
k = ((dim[0] + 1) - j);
if (k > formats[0]) k = formats[0];
GetIntsFromString (string, (vptr+j), k, formats[1], shft);
j+=formats[0];
}
j = 0;
for (i = 0; i < lines[2]; i++)
{
ReadStringFile (file, string, length2);
k = (dim[2] - j);
if (k > formats[2]) k = formats[2];
GetIntsFromString (string, (vpos+j), k, formats[3], shft);
j+=formats[2];
}
j = 0;
for (i = 0; i < lines[3]; i++)
{
ReadStringFile (file, string, length2);
k = (dim[2] - j);
if (k > formats[4]) k = formats[4];
GetDoublesFromString (string, (vval+j), k, formats[5]);
j+=formats[4];
}
fclose (file);
}
#ifndef SparseMatrixTip
#define SparseMatrixTip 1
typedef struct
{
int dim1, dim2;
int *vptr;
int *vpos;
double *vval;
} SparseMatrix, *ptr_SparseMatrix;
extern FILE *OpenFile (char *name, char *attr);
extern void ReadStringFile (FILE *file, char *string, int length);
extern int CreateSparseMatrix (ptr_SparseMatrix spr, int numR, int numC, int numE, int msr);
extern int CreateSparseMatrixVptr (ptr_SparseMatrix spr, int numR, int numC, int msr);
extern int CreateSparseMatrixValues (ptr_SparseMatrix spr, int numR, int numC, int numE, int msr);
extern int RemoveSparseMatrix (ptr_SparseMatrix spr);
extern int RemoveSparseMatrix2 (ptr_SparseMatrix spr);
extern int PrintSparseMatrix (SparseMatrix spr, int CorF);
extern int ProdSparseMatrixVector (SparseMatrix spr, double *vec, double *res);
extern int DesymmetrizeSparseMatrices (SparseMatrix src, ptr_SparseMatrix dst);
extern int ProdSymSparseMatrixVector (SparseMatrix spr, double *vec, double *res);
extern void CreateSparseMatrixHB (char *nameFile, ptr_SparseMatrix spr, int FtoC);
#endif
CC = gcc
MCC = mpicc
#C_FLAGS_ALL = -Wall -Wextra -Wshadow -Wfatal-errors -Wconversion -Wpedantic
C_FLAGS =
LD_FLAGS = -lm -pthread
DEF =
.PHONY : clean clear install install_slurm
# MKL MonoHebra
MKL_FSINGLE = -lmkl_blas95_lp64 -lmkl_lapack95_lp64 -lmkl_gf_lp64 -lmkl_sequential -lmkl_core -lpthread -lm
LIBMONO = -L$(DIR_MKL) $(MKL_FSINGLE)
# Final binary
BIN = a.out
# Put all auto generated stuff to this build dir.
BUILD_DIR = ./build
# List of all directories where source files are located
SRCDIRS = IOcodes Main malleability malleability/spawn_methods malleability/distribution_methods
# List of all .c source files.
C_FILES = $(foreach dire, $(SRCDIRS), $(wildcard $(dire)/*.c))
# All .o files go to build dir.
OBJ = $(C_FILES:%.c=$(BUILD_DIR)/%.o)
# Gcc will create these .d files containing dependencies.
DEP = $(OBJ:%.o=%.d)
# Default target named after the binary.
$(BIN) : $(BUILD_DIR)/$(BIN)
# Actual target of the binary - depends on all .o files.
$(BUILD_DIR)/$(BIN) : $(OBJ)
$(MCC) $(C_FLAGS) $^ -o $@ $(LD_FLAGS) $(LIBMONO)
# Include all .d files
# .d files are used for knowing the dependencies of each source file
-include $(DEP)
# Build target for every single object file.
# The potential dependency on header files is covered
# by calling `-include $(DEP)`.
# The -MMD flags additionaly creates a .d file with
# the same name as the .o file.
$(BUILD_DIR)/%.o : %.c
mkdir -p $(@D)
$(MCC) $(C_FLAGS) $(DEF) -MMD -c $< -o $@
clean:
-rm $(BUILD_DIR)/$(BIN) $(OBJ) $(DEP)
clear:
-rm -rf $(BUILDDIR)
install: $(BIN)
echo "Done"
# Builds target with slurm
install_slurm: LD_FLAGS += -lslurm
install_slurm: DEF += -DUSE_SLURM
install_slurm: install
CC = mpicc
CFLAGS = $(MKL_COPTIONS)
CLINKER = mpicc
F77 = mpif77
FFLAGS =
FLINKER = mpif77
LDFLAGS =
OPTFLAGS =
LIBLIST = $(LIBDIRS_4) $(LIBLIST_4)
LDLIBS += -lslurm
INCDIRS = -I/home/ulc/cursos/curso355/TFM/Compact_CG_2
EXECS = ConjugateGradient ConjugateGradient_mt
all: $(EXECS)
DIR_MKL=$(MKLRROT)/lib/intel64
# MKL MonoHebra
MKL_FSINGLE = -lmkl_blas95_lp64 -lmkl_lapack95_lp64 -lmkl_gf_lp64 -lmkl_sequential -lmkl_core -lpthread -lm
LIBMONO = -L$(DIR_MKL) $(MKL_FSINGLE)
# MKL MultiHebra_INTEL
MKL_FMULTIS_INTEL= -lmkl_blas95_lp64 -lmkl_lapack95_lp64 -lmkl_gf_lp64 -lmkl_intel_thread -lmkl_core -liomp5 -lpthread -lm
LIBMULTI = -L$(DIR_MKL) $(MKL_FMULTIS_INTEL)
#Test
ConjugateGradient: ConjugateGradient.o SparseMatrices.o ScalarVectors.o
$(CLINKER) $(LDFLAGS) $(OPTFLAGS) $(INCDIRS) -o ConjugateGradient ConjugateGradient.o SparseMatrices.o ScalarVectors.o $(LIBMONO) $(LDLIBS)
ConjugateGradient_mt: ConjugateGradient.o SparseMatrices.o ScalarVectors.o
$(CLINKER) $(LDFLAGS) $(OPTFLAGS) $(INCDIRS) -o ConjugateGradient_mt ConjugateGradient.o SparseMatrices.o ScalarVectors.o $(LIBMULTI) $(LDLIBS)
clean:
/bin/rm -rf core *.o $(EXECS)
.c.o:
echo compilando
$(CC) $(CFLAGS) $(LDLIBS) $(INCDIRS) -c $*.c
.f.o:
$(F77) $(FFLAGS) -c $*.f
.F.o:
$(F77) $(FFLAGS) -c $*.F
.h.h:
echo compilando
1SYMMETRIC STIFFNESS MATRIX SMALL GENERALIZED EIGENVALUE PROBLEM BCSSTK01
74 4 14 56 0
RSA 48 48 224 0
(16I5) (16I5) (4E20.12)
1 9 17 25 31 37 43 49 55 62 66 70 75 85 95 104
112 120 127 132 136 141 144 146 149 154 158 161 164 167 169 173
178 183 185 188 191 196 201 205 208 211 213 216 219 221 222 224
225
1 5 6 7 11 19 25 30 2 4 6 8 10 20 24 26
3 4 5 9 21 23 27 28 4 8 10 22 27 28 5 7
11 21 23 29 6 12 20 24 25 30 7 11 12 13 31 36
8 10 12 14 18 32 9 10 11 15 17 33 34 10 16 33
34 11 15 17 35 12 14 18 31 36 13 17 18 19 23 37
42 43 47 48 14 15 16 18 20 22 38 44 45 46 15 16
17 21 39 40 44 45 46 16 20 22 39 40 44 45 46 17
18 19 23 41 43 47 48 18 24 37 42 43 47 48 19 23
24 43 48 20 22 24 44 21 22 23 45 46 22 45 46 23
47 24 43 48 25 29 30 31 35 26 28 32 34 27 28 33
28 32 34 29 31 35 30 36 31 35 36 37 32 34 36 38
42 33 34 35 39 41 34 40 35 39 41 36 38 42 37 41
42 43 47 38 40 42 44 46 39 40 41 45 40 44 46 41
43 47 42 48 43 47 48 44 45 46 45 46 46 47 48 48
.283226851852E+07 .100000000000E+07 .208333333333E+07 -.333333333333E+04
.100000000000E+07 -.280000000000E+07 -.289351851852E+05 .208333333333E+07
.163544753086E+07 -.200000000000E+07 .555555555555E+07 -.666666666667E+04
-.200000000000E+07 -.308641975309E+05 .555555555555E+07 -.159791666667E+07
.172436728395E+07 -.208333333333E+07 -.277777777778E+07 -.168000000000E+07
-.154320987654E+05 -.277777777778E+07 -.289351851852E+05 -.208333333333E+07
.100333333333E+10 .200000000000E+07 .400000000000E+09 -.333333333333E+07
.208333333333E+07 .100000000000E+09 .106750000000E+10 -.100000000000E+07
.200000000000E+09 .277777777778E+07 .333333333333E+09 -.833333333333E+06
.153533333333E+10 -.200000000000E+07 -.555555555555E+07 .666666666667E+09
-.208333333333E+07 .100000000000E+09 .283226851852E+07 -.100000000000E+07
.208333333333E+07 -.280000000000E+07 -.289351851852E+05 .208333333333E+07
.163544753086E+07 .200000000000E+07 .555555555555E+07 -.308641975309E+05
.555555555555E+07 -.159791666667E+07 .172436728395E+07 -.208333333333E+07
-.277777777778E+07 -.154320987654E+05 -.277777777778E+07 -.289351851852E+05
-.208333333333E+07 .100333333333E+10 -.333333333333E+07 .208333333333E+07
.100000000000E+09 .106750000000E+10 .277777777778E+07 .333333333333E+09
-.833333333333E+06 .153533333333E+10 -.555555555555E+07 .666666666667E+09
-.208333333333E+07 .100000000000E+09 .283609946950E+07 -.214928529451E+07
.235916180402E+07 -.333333333333E+04 -.100000000000E+07 -.289351851852E+05
.208333333333E+07 -.383095098171E+04 -.114928529451E+07 .275828470683E+06
.176741074446E+07 .517922131816E+06 .429857058902E+07 -.555555555555E+07
-.666666666667E+04 .200000000000E+07 -.159791666667E+07 -.131963213599E+06
-.517922131816E+06 .229857058902E+07 .389003806848E+07 -.263499027470E+07
.277777777778E+07 -.168000000000E+07 -.289351851852E+05 -.208333333333E+07
-.517922131816E+06 -.216567078453E+07 -.551656941367E+06 .197572063531E+10
-.200000000000E+07 .400000000000E+09 .208333333333E+07 .100000000000E+09
-.229857058902E+07 .551656941366E+06 .486193650990E+09 .152734651547E+10
-.109779731332E+09 .100000000000E+07 .200000000000E+09 -.833333333333E+06
.114928529451E+07 .229724661236E+09 -.557173510779E+08 .156411143711E+10
-.200000000000E+07 -.208333333333E+07 .100000000000E+09 -.275828470683E+06
-.557173510779E+08 .109411960038E+08 .283226851852E+07 .100000000000E+07
.208333333333E+07 -.289351851852E+05 .208333333333E+07 .163544753086E+07
-.200000000000E+07 -.555555555555E+07 -.159791666667E+07 .172436728395E+07
-.208333333333E+07 .277777777778E+07 -.289351851852E+05 -.208333333333E+07
.100333333333E+10 .208333333333E+07 .100000000000E+09 .106750000000E+10
-.833333333333E+06 .153533333333E+10 -.208333333333E+07 .100000000000E+09
.608796296296E+05 .125000000000E+07 .416666666667E+06 -.416666666667E+04
.125000000000E+07 .337291666667E+07 -.250000000000E+07 -.833333333333E+04
-.250000000000E+07 .241171296296E+07 -.416666666667E+06 -.235500000000E+07
.150000000000E+10 .250000000000E+07 .500000000000E+09 .501833333333E+09
-.125000000000E+07 .250000000000E+09 .502500000000E+09 -.250000000000E+07
.398587962963E+07 -.125000000000E+07 .416666666667E+06 -.392500000000E+07
.341149691358E+07 .250000000000E+07 .694444444444E+07 -.385802469136E+05
.694444444445E+07 .243100308642E+07 -.416666666667E+06 -.347222222222E+07
-.192901234568E+05 -.347222222222E+07 .150416666667E+10 -.416666666667E+07
.133516666667E+10 .347222222222E+07 .416666666667E+09 .216916666667E+10
-.694444444444E+07 .833333333333E+09 .398587962963E+07 -.125000000000E+07
.416666666667E+06 -.416666666667E+04 -.125000000000E+07 .341149691358E+07
.250000000000E+07 -.694444444445E+07 -.833333333333E+04 .250000000000E+07
.243100308642E+07 -.416666666667E+06 .347222222222E+07 -.235500000000E+07
.150416666667E+10 -.250000000000E+07 .500000000000E+09 .133516666667E+10
.125000000000E+07 .250000000000E+09 .216916666667E+10 -.250000000000E+07
.647105806113E+05 .239928529451E+07 .140838195984E+06 .350487988027E+07
.517922131816E+06 -.479857058902E+07 .457738374749E+07 .134990274700E+06
.247238730198E+10 .961679848804E+09 -.109779731332E+09 .531278103775E+09
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#ifndef COMMDIST_H
#define COMMDIST_H
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <string.h>
#include "malleabilityStates.h"
//#define MAL_COMM_COMPLETED 0
//#define MAL_COMM_UNINITIALIZED 2
//#define MAL_ASYNC_PENDING 1
//#define MAL_USE_NORMAL 0
//#define MAL_USE_IBARRIER 1
//#define MAL_USE_POINT 2
//#define MAL_USE_THREAD 3
int sync_communication(char *send, char **recv, int qty, int myId, int numP, int numO, int is_children_group, int comm_type, MPI_Comm comm);
int async_communication(char *send, char **recv, int qty, int myId, int numP, int numO, int is_children_group, int red_method, int red_strategies, MPI_Comm comm, MPI_Request **requests, size_t *request_qty);
int send_async(char *array, int qty, int myId, int numP, MPI_Comm intercomm, int numP_child, MPI_Request **comm_req, int red_method, int red_strategies);
void recv_async(char **array, int qty, int myId, int numP, MPI_Comm intercomm, int numP_parents, int red_method, int red_strategies);
void malloc_comm_array(char **array, int qty, int myId, int numP);
int malleability_red_contains_strat(int comm_strategies, int strategy, int *result);
#endif
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include "block_distribution.h"
void set_interblock_counts(int id, int numP, struct Dist_data data_dist, int offset_ids, int *sendcounts);
void get_util_ids(struct Dist_data dist_data, int numP_other, int **idS);
/*
* Prepares a communication from "numP" processes to "numP_other" processes
* of "n" elements an returns an struct of counts with 3 arrays to perform the
* communications.
*
* The struct should be freed with freeCounts
*/
void prepare_comm_alltoall(int myId, int numP, int numP_other, int n, int offset_ids, struct Counts *counts) {
int i, *idS, first_id = 0;
struct Dist_data dist_data, dist_target;
if(counts == NULL) {
fprintf(stderr, "Counts is NULL for rank %d/%d ", myId, numP);
MPI_Abort(MPI_COMM_WORLD, -3);
}
get_block_dist(n, myId, numP, &dist_data);
get_util_ids(dist_data, numP_other, &idS);
counts->idI = idS[0] + offset_ids;
counts->idE = idS[1] + offset_ids;
get_block_dist(n, idS[0], numP_other, &dist_target); // RMA Specific operation -- uses idS[0], not idI
counts->first_target_displs = dist_data.ini - dist_target.ini; // RMA Specific operation
if(idS[0] == 0) { // Uses idS[0], not idI
set_interblock_counts(counts->idI, numP_other, dist_data, offset_ids, counts->counts);
first_id++;
}
for(i=counts->idI + first_id; i<counts->idE; i++) {
set_interblock_counts(i, numP_other, dist_data, offset_ids, counts->counts);
counts->displs[i] = counts->displs[i-1] + counts->counts[i-1];
}
free(idS);
for(i=0; i<numP_other; i++) {
if(counts->counts[i] < 0) {
fprintf(stderr, "Counts value [i=%d/%d] is negative for rank %d/%d ", i, numP_other, myId, numP);
MPI_Abort(MPI_COMM_WORLD, -3);
}
if(counts->displs[i] < 0) {
fprintf(stderr, "Displs value [i=%d/%d] is negative for rank %d/%d ", i, numP_other, myId, numP);
MPI_Abort(MPI_COMM_WORLD, -3);
}
}
}
/*
* Prepares a communication of "numP" processes of "n" elements an
* returns an struct of counts with 3 arrays to perform the
* communications.
*
* The struct should be freed with freeCounts
*/
void prepare_comm_allgatherv(int numP, int n, struct Counts *counts) {
int i;
struct Dist_data dist_data;
mallocCounts(counts, numP);
get_block_dist(n, 0, numP, &dist_data);
counts->counts[0] = dist_data.tamBl;
for(i=1; i<numP; i++){
get_block_dist(n, i, numP, &dist_data);
counts->counts[i] = dist_data.tamBl;
counts->displs[i] = counts->displs[i-1] + counts->counts[i-1];
}
}
/*
* ========================================================================================
* ========================================================================================
* ================================DISTRIBUTION FUNCTIONS==================================
* ========================================================================================
* ========================================================================================
*/
/*
* Obatains for "Id" and "numP", how many
* elements per row will have process "Id"
* and fills the results in a Dist_data struct
*/
void get_block_dist(int qty, int id, int numP, struct Dist_data *dist_data) {
int rem;
dist_data->myId = id;
dist_data->numP = numP;
dist_data->qty = qty;
dist_data->tamBl = qty / numP;
rem = qty % numP;
if(id < rem) { // First subgroup
dist_data->ini = id * dist_data->tamBl + id;
dist_data->fin = (id+1) * dist_data->tamBl + (id+1);
} else { // Second subgroup
dist_data->ini = id * dist_data->tamBl + rem;
dist_data->fin = (id+1) * dist_data->tamBl + rem;
}
if(dist_data->fin > qty) {
dist_data->fin = qty;
}
if(dist_data->ini > dist_data->fin) {
dist_data->ini = dist_data->fin;
}
dist_data->tamBl = dist_data->fin - dist_data->ini;
}
/*
* Obtiene para el Id de un proceso dado, cuantos elementos
* enviara o recibira desde el proceso indicado en Dist_data.
*/
void set_interblock_counts(int id, int numP, struct Dist_data data_dist, int offset_ids, int *sendcounts) {
struct Dist_data other;
int biggest_ini, smallest_end;
get_block_dist(data_dist.qty, id - offset_ids, numP, &other);
// Si el rango de valores no coincide, se pasa al siguiente proceso
if(data_dist.ini >= other.fin || data_dist.fin <= other.ini) {
return;
}
// Obtiene el proceso con mayor ini entre los dos procesos
if(data_dist.ini > other.ini) {
biggest_ini = data_dist.ini;
} else {
biggest_ini = other.ini;
}
// Obtiene el proceso con menor fin entre los dos procesos
if(data_dist.fin < other.fin) {
smallest_end = data_dist.fin;
} else {
smallest_end = other.fin;
}
sendcounts[id] = smallest_end - biggest_ini; // Numero de elementos a enviar/recibir del proceso Id
}
/*
* Obtiene para un proceso de un grupo a que rango procesos de
* otro grupo tiene que enviar o recibir datos.
*
* Devuelve el primer identificador y el último (Excluido) con el que
* comunicarse.
*/
void get_util_ids(struct Dist_data dist_data, int numP_other, int **idS) {
int idI, idE;
int tamOther = dist_data.qty / numP_other;
int remOther = dist_data.qty % numP_other;
// Indica el punto de corte del grupo de procesos externo que
// divide entre los procesos que tienen
// un tamaño tamOther + 1 y un tamaño tamOther
int middle = (tamOther + 1) * remOther;
// Calcular idI teniendo en cuenta si se comunica con un
// proceso con tamano tamOther o tamOther+1
if(middle > dist_data.ini) { // First subgroup (tamOther+1)
idI = dist_data.ini / (tamOther + 1);
} else { // Second subgroup (tamOther)
idI = ((dist_data.ini - middle) / tamOther) + remOther;
}
// Calcular idR teniendo en cuenta si se comunica con un
// proceso con tamano tamOther o tamOther+1
if(middle >= dist_data.fin) { // First subgroup (tamOther +1)
idE = dist_data.fin / (tamOther + 1);
idE = (dist_data.fin % (tamOther + 1) > 0 && idE+1 <= numP_other) ? idE+1 : idE;
} else { // Second subgroup (tamOther)
idE = ((dist_data.fin - middle) / tamOther) + remOther;
idE = ((dist_data.fin - middle) % tamOther > 0 && idE+1 <= numP_other) ? idE+1 : idE;
}
*idS = malloc(2 * sizeof(int));
(*idS)[0] = idI;
(*idS)[1] = idE;
}
/*
* ========================================================================================
* ========================================================================================
* ==============================INIT/FREE/PRINT FUNCTIONS=================================
* ========================================================================================
* ========================================================================================
*/
/*
* Reserva memoria para los vectores de counts/displs de la funcion
* MPI_Alltoallv. Todos los vectores tienen un tamaño de numP, que es la
* cantidad de procesos en el otro grupo de procesos.
*
* El vector counts indica cuantos elementos se comunican desde este proceso
* al proceso "i" del otro grupo.
*
* El vector displs indica los desplazamientos necesarios para cada comunicacion
* con el proceso "i" del otro grupo.
*
*/
void mallocCounts(struct Counts *counts, size_t numP) {
counts->counts = calloc(numP, sizeof(int));
if(counts->counts == NULL) { MPI_Abort(MPI_COMM_WORLD, -2);}
counts->displs = calloc(numP, sizeof(int));
if(counts->displs == NULL) { MPI_Abort(MPI_COMM_WORLD, -2);}
counts->len = numP;
counts->idI = -1;
counts->idE = -1;
counts->first_target_displs = -1;
}
/*
* Libera la memoria interna de una estructura Counts.
*
* No libera la memoria de la estructura counts si se ha alojado
* de forma dinamica.
*/
void freeCounts(struct Counts *counts) {
if(counts == NULL) {
return;
}
if(counts->counts != NULL) {
free(counts->counts);
counts->counts = NULL;
}
if(counts->displs != NULL) {
free(counts->displs);
counts->displs = NULL;
}
}
/*
* Muestra la informacion de comunicaciones de un proceso
* Si se activa la bandera "include_zero" a verdadero se mostraran para el vector
* xcounts los valores a 0.
*
* En "name" se puede indicar un string con el fin de identificar mejor a que vectores
* se refiere la llamada.
*/
void print_counts(struct Dist_data data_dist, int *xcounts, int *xdispls, int size, int include_zero, const char* name) {
int i;
for(i=0; i < size; i++) {
if(xcounts[i] != 0 || include_zero) {
printf("P%d of %d | %scounts[%d]=%d disp=%d\n", data_dist.myId, data_dist.numP, name, i, xcounts[i], xdispls[i]);
}
}
}
#ifndef mall_block_distribution
#define mall_block_distribution
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
struct Dist_data {
int ini; //Primer elemento a enviar
int fin; //Ultimo elemento a enviar
int tamBl; // Total de elementos
int qty; // Total number of rows of the full disperse matrix
int myId;
int numP;
MPI_Comm intercomm;
};
struct Counts {
int len, idI, idE;
int first_target_displs; // RMA. Indicates displacement for first target when performing a Get.
int *counts;
int *displs;
};
void prepare_comm_alltoall(int myId, int numP, int numP_other, int n, int offset_ids, struct Counts *counts);
void prepare_comm_allgatherv(int numP, int n, struct Counts *counts);
void get_block_dist(int qty, int id, int numP, struct Dist_data *dist_data);
void mallocCounts(struct Counts *counts, size_t numP);
void freeCounts(struct Counts *counts);
void print_counts(struct Dist_data data_dist, int *xcounts, int *xdispls, int size, int include_zero, const char* name);
#endif
#ifndef MALLEABILITY_DATA_STRUCTURES_H
#define MALLEABILITY_DATA_STRUCTURES_H
/*
* Shows available data structures for inner ussage.
*/
#include <mpi.h>
/* --- SPAWN STRUCTURES --- */
struct physical_dist {
int num_cpus, num_nodes;
char *nodelist;
int target_qty, already_created;
int dist_type, info_type;
};
typedef struct {
int myId, root, root_parents;
int spawn_qty, initial_qty, target_qty;
int already_created;
int spawn_method, spawn_is_single, spawn_is_async;
char *cmd; //Executable name
MPI_Info mapping;
MPI_Datatype dtype;
struct physical_dist dist; // Used to create mapping var
MPI_Comm comm, returned_comm;
} Spawn_data;
#endif
This diff is collapsed.
#ifndef MALLEABILITY_MANAGER_H
#define MALLEABILITY_MANAGER_H
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <mpi.h>
#include "malleabilityStates.h"
int init_malleability(int myId, int numP, int root, MPI_Comm comm, char *name_exec, char *nodelist, int num_cpus, int num_nodes);
void free_malleability();
int malleability_checkpoint();
void set_benchmark_grp(int grp);
void set_malleability_configuration(int spawn_method, int spawn_strategies, int spawn_dist, int red_method, int red_strategies);
void set_children_number(int numC); // TODO TO BE DEPRECATED
void get_malleability_user_comm(MPI_Comm *comm);
void malleability_add_data(void *data, size_t total_qty, int type, int is_replicated, int is_constant);
void malleability_modify_data(void *data, size_t index, size_t total_qty, int type, int is_replicated, int is_constant);
void malleability_get_entries(size_t *entries, int is_replicated, int is_constant);
void malleability_get_data(void **data, size_t index, int is_replicated, int is_constant);
#endif
#ifndef MALLEABILITY_STATES_H
#define MALLEABILITY_STATES_H
#include <stdio.h>
#include <stdlib.h>
//States
#define MALL_DENIED -1
enum mall_states{MALL_UNRESERVED, MALL_NOT_STARTED, MALL_ZOMBIE, MALL_SPAWN_PENDING, MALL_SPAWN_SINGLE_PENDING,
MALL_SPAWN_SINGLE_COMPLETED, MALL_SPAWN_ADAPT_POSTPONE, MALL_SPAWN_COMPLETED, MALL_DIST_PENDING, MALL_DIST_COMPLETED,
MALL_SPAWN_ADAPT_PENDING, MALL_SPAWN_ADAPTED, MALL_COMPLETED};
enum mall_spawn_methods{MALL_SPAWN_BASELINE, MALL_SPAWN_MERGE};
#define MALL_SPAWN_PTHREAD 2
#define MALL_SPAWN_SINGLE 3
enum mall_redistribution_methods{MALL_RED_BASELINE, MALL_RED_POINT, MALL_RED_RMA_LOCK, MALL_RED_RMA_LOCKALL, MALL_RED_IBARRIER};
#define MALL_RED_THREAD 2
//#define MALL_RED_IBARRIER 3 Agregar como estrategia y eliminar como método
#define MALLEABILITY_ROOT 0
#define MAL_APP_EXECUTING 0
#define MAL_APP_ENDED 1
//TODO DEPRECATE
#define MAL_INT 0
#define MAL_CHAR 1
#define MAL_DOUBLE 2
////////////////
#define MALLEABILITY_CHILDREN 1
#define MALLEABILITY_NOT_CHILDREN 0
#endif
#include "malleabilityTypes.h"
void init_malleability_data_struct(malleability_data_t *data_struct, size_t size);
void realloc_malleability_data_struct(malleability_data_t *data_struct, size_t qty_to_add);
void def_malleability_entries(malleability_data_t *data_struct_rep, malleability_data_t *data_struct_dist, MPI_Datatype *new_type);
void def_malleability_qty_type(malleability_data_t *data_struct_rep, malleability_data_t *data_struct_dist, MPI_Datatype *new_type);
//======================================================||
//======================================================||
//===================PUBLIC FUNCTIONS===================||
//======================================================||
//======================================================||
/*
* Anyade en la estructura de datos a comunicar con los hijos
* un nuevo set de datos de un total "total_qty" distribuido entre
* todos los padres. La nueva serie "data" solo representa los datos
* que tiene este padre.
*/
void add_data(void *data, size_t total_qty, int type, size_t request_qty, malleability_data_t *data_struct) {
size_t i;
if(data_struct->entries == 0) {
init_malleability_data_struct(data_struct, MALLEABILITY_INIT_DATA_QTY);
} else if(data_struct->entries == data_struct->max_entries) {
realloc_malleability_data_struct(data_struct, MALLEABILITY_INIT_DATA_QTY);
}
data_struct->qty[data_struct->entries] = total_qty;
data_struct->types[data_struct->entries] = type;
data_struct->arrays[data_struct->entries] = data;
data_struct->request_qty[data_struct->entries] = request_qty;
if(request_qty) {
data_struct->requests[data_struct->entries] = (MPI_Request *) malloc(request_qty * sizeof(MPI_Request));
for(i=0; i < request_qty; i++) {
data_struct->requests[data_struct->entries][i] = MPI_REQUEST_NULL;
}
}
data_struct->entries+=1;
}
/*
* Modifica en la estructura de datos a comunicar con los hijos
* un set de datos de un total "total_qty" distribuido entre
* todos los padres. La nueva serie "data" solo representa los datos
* que tiene este padre.
*/
void modify_data(void *data, size_t index, size_t total_qty, int type, size_t request_qty, malleability_data_t *data_struct) {
size_t i;
if(data_struct->entries < index) { // Index does not exist
return;
}
if(data_struct->requests[index] != NULL) {
//free(data_struct->requests[index]); TODO Error when trying to free
data_struct->requests[index] = NULL;
}
data_struct->qty[index] = total_qty;
data_struct->types[index] = type;
data_struct->arrays[index] = data;
data_struct->request_qty[index] = request_qty;
if(request_qty) {
data_struct->requests[index] = (MPI_Request *) malloc(request_qty * sizeof(MPI_Request));
for(i=0; i < request_qty; i++) {
data_struct->requests[index][i] = MPI_REQUEST_NULL;
}
}
}
/*
* Comunicar desde los padres a los hijos las estructuras de datos sincronas o asincronas
* No es necesario que las estructuras esten inicializadas para un buen funcionamiento.
*
* En el argumento "root" todos tienen que indicar quien es el proceso raiz de los padres
* unicamente.
*/
void comm_data_info(malleability_data_t *data_struct_rep, malleability_data_t *data_struct_dist, int is_children_group, int myId, int root, MPI_Comm intercomm) {
int is_intercomm, rootBcast = MPI_PROC_NULL;
size_t i, j;
MPI_Datatype entries_type, struct_type;
MPI_Comm_test_inter(intercomm, &is_intercomm);
if(is_intercomm && !is_children_group) {
rootBcast = myId == root ? MPI_ROOT : MPI_PROC_NULL;
} else {
rootBcast = root;
}
// Mandar primero numero de entradas
def_malleability_entries(data_struct_dist, data_struct_rep, &entries_type);
MPI_Bcast(MPI_BOTTOM, 1, entries_type, rootBcast, intercomm);
if(is_children_group && ( data_struct_rep->entries != 0 || data_struct_dist->entries != 0 )) {
init_malleability_data_struct(data_struct_rep, data_struct_rep->entries);
init_malleability_data_struct(data_struct_dist, data_struct_dist->entries);
}
def_malleability_qty_type(data_struct_dist, data_struct_rep, &struct_type);
MPI_Bcast(MPI_BOTTOM, 1, struct_type, rootBcast, intercomm);
if(is_children_group) {
for(i=0; i < data_struct_rep->entries; i++) {
data_struct_rep->arrays[i] = (void *) malloc(data_struct_rep->qty[i] * sizeof(int)); //TODO Tener en cuenta que no siempre es int
data_struct_rep->requests[i] = (MPI_Request *) malloc(data_struct_rep->request_qty[i] * sizeof(MPI_Request));
for(j=0; j < data_struct_rep->request_qty[i]; j++) {
data_struct_rep->requests[i][j] = MPI_REQUEST_NULL;
}
}
for(i=0; i < data_struct_dist->entries; i++) {
data_struct_dist->arrays[i] = (void *) NULL;
data_struct_dist->requests[i] = (MPI_Request *) malloc(data_struct_dist->request_qty[i] * sizeof(MPI_Request));
for(j=0; j < data_struct_dist->request_qty[i]; j++) {
data_struct_dist->requests[i][j] = MPI_REQUEST_NULL;
}
}
}
MPI_Type_free(&entries_type);
MPI_Type_free(&struct_type);
}
//======================================================||
//======================================================||
//=========INIT/REALLOC/FREE RESULTS FUNCTIONS==========||
//======================================================||
//======================================================||
/*
* Inicializa la estructura que describe una serie de datos con las mismas
* caracteristicas de localización y uso. Se inicializa para utilizar hasta
* "size" elementos.
*/
void init_malleability_data_struct(malleability_data_t *data_struct, size_t size) {
size_t i;
data_struct->max_entries = size;
data_struct->qty = (size_t *) malloc(size * sizeof(size_t));
data_struct->types = (int *) malloc(size * sizeof(int));
data_struct->request_qty = (size_t *) malloc(size * sizeof(size_t));
data_struct->requests = (MPI_Request **) malloc(size * sizeof(MPI_Request *));
data_struct->arrays = (void **) malloc(size * sizeof(void *));
for(i=0; i<size; i++) { //calloc and memset does not ensure a NULL value
data_struct->requests[i] = NULL;
data_struct->arrays[i] = NULL;
}
}
/*
* Realoja la estructura que describe una serie de datos con las mismas
* caracteristicas de localización y uso. Se anyaden "size" entradas nuevas
* a las ya existentes.
*/
void realloc_malleability_data_struct(malleability_data_t *data_struct, size_t qty_to_add) {
size_t i, needed, *qty_aux, *request_qty_aux;
int *types_aux;
MPI_Request **requests_aux;
void **arrays_aux;
needed = data_struct->max_entries + qty_to_add;
qty_aux = (size_t *) realloc(data_struct->qty, needed * sizeof(int));
types_aux = (int *) realloc(data_struct->types, needed * sizeof(int));
request_qty_aux = (size_t *) realloc(data_struct->request_qty, needed * sizeof(int));
requests_aux = (MPI_Request **) realloc(data_struct->requests, needed * sizeof(MPI_Request *));
arrays_aux = (void **) realloc(data_struct->arrays, needed * sizeof(void *));
if(qty_aux == NULL || arrays_aux == NULL || requests_aux == NULL || types_aux == NULL || request_qty_aux == NULL) {
fprintf(stderr, "Fatal error - No se ha podido realojar la memoria constante de datos a redistribuir/comunicar\n");
MPI_Abort(MPI_COMM_WORLD, 1);
}
for(i=data_struct->max_entries; i<needed; i++) { //calloc and memset does not ensure a NULL value
requests_aux[i] = NULL;
arrays_aux[i] = NULL;
}
data_struct->qty = qty_aux;
data_struct->types = types_aux;
data_struct->request_qty = request_qty_aux;
data_struct->requests = requests_aux;
data_struct->arrays = arrays_aux;
data_struct->max_entries = needed;
}
void free_malleability_data_struct(malleability_data_t *data_struct) {
size_t i, j, max;
max = data_struct->entries;
if(max != 0) {
for(i=0; i<max; i++) {
//free(data_struct->arrays[i]); //FIXME Valores alojados con 1 elemento no se liberan?
}
if(data_struct->qty != NULL) {
free(data_struct->qty);
}
if(data_struct->types != NULL) {
free(data_struct->types);
}
if(data_struct->requests != NULL && data_struct->request_qty != NULL) {
for(i=0; i<max; i++) {
if(data_struct->requests[i] != NULL) {
for(j=0; j<data_struct->request_qty[i]; j++) {
if(data_struct->requests[i][j] != MPI_REQUEST_NULL) {
MPI_Request_free(&(data_struct->requests[i][j]));
data_struct->requests[i][j] = MPI_REQUEST_NULL;
}
}
free(data_struct->requests[i]);
}
}
free(data_struct->request_qty);
free(data_struct->requests);
}
if(data_struct->arrays != NULL) {
free(data_struct->arrays);
}
}
}
//======================================================||
//======================================================||
//================MPI DERIVED DATATYPES=================||
//======================================================||
//======================================================||
/*
* Crea un tipo derivado para mandar el numero de entradas
* en dos estructuras de descripcion de datos.
*/
void def_malleability_entries(malleability_data_t *data_struct_rep, malleability_data_t *data_struct_dist, MPI_Datatype *new_type) {
int counts = 2;
int blocklengths[counts];
MPI_Aint displs[counts];
MPI_Datatype types[counts];
blocklengths[0] = blocklengths[1] = 1;
types[0] = types[1] = MPI_UNSIGNED_LONG;
// Obtener direccion base
MPI_Get_address(&(data_struct_rep->entries), &displs[0]);
MPI_Get_address(&(data_struct_dist->entries), &displs[1]);
MPI_Type_create_struct(counts, blocklengths, displs, types, new_type);
MPI_Type_commit(new_type);
}
/*
* Crea un tipo derivado para mandar las cantidades y tipo
* de datos de dos estructuras de descripcion de datos.
* El vector de "requests" no es enviado ya que solo es necesario
* en los padres.
* TODO Refactor?
*/
void def_malleability_qty_type(malleability_data_t *data_struct_rep, malleability_data_t *data_struct_dist, MPI_Datatype *new_type) {
int counts = 6;
int blocklengths[counts];
MPI_Aint displs[counts];
MPI_Datatype types[counts];
types[0] = types[1] = types[3] = types[4] = MPI_UNSIGNED_LONG;
types[2] = types[5] = MPI_INT;
blocklengths[0] = blocklengths[1] = blocklengths[2] = data_struct_rep->entries;
blocklengths[3] = blocklengths[4] = blocklengths[5] = data_struct_dist->entries;
MPI_Get_address((data_struct_rep->qty), &displs[0]);
MPI_Get_address((data_struct_rep->request_qty), &displs[1]);
MPI_Get_address((data_struct_rep->types), &displs[2]);
MPI_Get_address((data_struct_dist->qty), &displs[3]);
MPI_Get_address((data_struct_dist->request_qty), &displs[4]);
MPI_Get_address((data_struct_dist->types), &displs[5]);
MPI_Type_create_struct(counts, blocklengths, displs, types, new_type);
MPI_Type_commit(new_type);
}
#ifndef MALLEABILITY_TYPES_H
#define MALLEABILITY_TYPES_H
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <fcntl.h>
#include <sys/stat.h>
#include "malleabilityStates.h"
#define MALLEABILITY_INIT_DATA_QTY 100
typedef struct {
size_t entries; // Indica numero de vectores a comunicar (replicated data)
size_t max_entries;
size_t *qty; // Indica numero de elementos en cada subvector de sync_array
int *types;
// Vector de vectores de request. En cada elemento superior se indican los requests a comprobar para dar por finalizada
// la comunicacion de ese dato
size_t *request_qty;
MPI_Request **requests;
void **arrays; // Cada subvector es una serie de datos a comunicar
} malleability_data_t;
void add_data(void *data, size_t total_qty, int type, size_t request_qty, malleability_data_t *data_struct);
void modify_data(void *data, size_t index, size_t total_qty, int type, size_t request_qty, malleability_data_t *data_struct);
void comm_data_info(malleability_data_t *data_struct_rep, malleability_data_t *data_struct_dist, int is_children_group, int myId, int root, MPI_Comm intercomm);
void free_malleability_data_struct(malleability_data_t *data_struct);
#endif
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment