| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 | /* StarPU --- Runtime system for heterogeneous multicore architectures. * * Copyright (C) 2009-2011  Université de Bordeaux * Copyright (C) 2010  Mehdi Juhoor <mjuhoor@gmail.com> * Copyright (C) 2010, 2011, 2012  CNRS * * StarPU is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or (at * your option) any later version. * * StarPU is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * See the GNU Lesser General Public License in COPYING.LGPL for more details. */#include "cholesky.h"#include "cholesky_kernels.h"#define __heap  __attribute__ ((heap_allocated))/* *	code to bootstrap the factorization *	and construct the DAG */static void dw_cholesky(unsigned nblocks, unsigned size, unsigned ld,			float matA[nblocks][nblocks][size/nblocks * size/nblocks]){	struct timeval start;	struct timeval end;        int x, y;	/* create all the DAG nodes */	unsigned i,j,k;        for(x = 0; x < nblocks ;  x++) {                for (y = 0; y < nblocks; y++) {#pragma starpu register matA[x][y]		}        }	gettimeofday(&start, NULL);	for (k = 0; k < nblocks; k++)        {#ifdef STARPU_DEVEL#  warning deal with prio and models#endif//                int prio = STARPU_DEFAULT_PRIO;//                if (!noprio) prio = STARPU_MAX_PRIO;		chol_codelet_update_u11(matA[k][k], size/nblocks, ld);		for (j = k+1; j<nblocks; j++)		{//                        prio = STARPU_DEFAULT_PRIO;//                        if (!noprio&& (j == k+1)) prio = STARPU_MAX_PRIO;			chol_codelet_update_u21(matA[k][k], matA[k][j], ld, ld, size/nblocks, size/nblocks);			for (i = k+1; i<nblocks; i++)			{				if (i <= j)                                {//                                        prio = STARPU_DEFAULT_PRIO;//                                        if (!noprio && (i == k + 1) && (j == k +1) ) prio = STARPU_MAX_PRIO;					chol_codelet_update_u22(matA[k][i],								matA[k][j],								matA[i][j],								size/nblocks, size/nblocks, size/nblocks, ld, ld, ld);                                }			}		}        }#pragma starpu wait        for(x = 0; x < nblocks ;  x++) {                for (y = 0; y < nblocks; y++) {#pragma starpu unregister matA[x][y]                }        }	gettimeofday(&end, NULL);	double timing = (double)((end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec));	fprintf(stderr, "Computation took (in ms)\n");	fprintf(stdout, "%2.2f\n", timing/1000);	double flop = (1.0f*size*size*size)/3.0f;	fprintf(stderr, "Synthetic GFlops : %2.2f\n", (flop/timing/1000.0f));}int main(int argc, char **argv){	/* create a simple definite positive symetric matrix example	 *	 *	Hilbert matrix : h(i,j) = 1/(i+j+1)	 * */	parse_args(argc, argv);#ifdef STARPU_DEVEL#  warning todo#endif//	struct starpu_conf conf;//	starpu_conf_init(&conf);//	conf.sched_policy_name = "dmda";//	conf.calibrate = 1;#pragma starpu initialize        starpu_cublas_init();	float bmat[nblocks][nblocks][BLOCKSIZE * BLOCKSIZE] __heap;	unsigned i,j,x,y;        for(x=0 ; x<nblocks ; x++)	{                for(y=0 ; y<nblocks ; y++)		{			for (i = 0; i < BLOCKSIZE; i++)			{				for (j = 0; j < BLOCKSIZE; j++)				{                                        bmat[x][y][j +i*BLOCKSIZE] = (1.0f/(1.0f+(i+(x*BLOCKSIZE)+j+(y*BLOCKSIZE)))) + ((i+(x*BLOCKSIZE) == j+(y*BLOCKSIZE))?1.0f*size:0.0f);					//mat[j +i*size] = ((i == j)?1.0f*size:0.0f);				}			}		}	}        if (display) {		for(y=0 ; y<nblocks ; y++)		{			for(x=0 ; x<nblocks ; x++)			{                                printf("Block %u,%u :\n", x, y);				for (j = 0; j < BLOCKSIZE; j++)				{					for (i = 0; i < BLOCKSIZE; i++)					{						if (i <= j) {							printf("%2.2f\t", bmat[y][x][j +i*BLOCKSIZE]);						}						else {							printf(".\t");						}					}					printf("\n");				}			}		}	}	dw_cholesky(nblocks, size, size/nblocks, bmat);        if (display) {                printf("Results:\n");		for(y=0 ; y<nblocks ; y++)		{			for(x=0 ; x<nblocks ; x++)			{                                printf("Block %u,%u :\n", x, y);				for (j = 0; j < BLOCKSIZE; j++)				{					for (i = 0; i < BLOCKSIZE; i++)					{						if (i <= j) {							printf("%2.2f\t", bmat[y][x][j +i*BLOCKSIZE]);						}						else {							printf(".\t");						}					}					printf("\n");				}			}		}	}	float rmat[size * size] __heap;        for(x=0 ; x<nblocks ; x++) {                for(y=0 ; y<nblocks ; y++) {                        for (i = 0; i < BLOCKSIZE; i++) {                                for (j = 0; j < BLOCKSIZE; j++) {                                        rmat[j+(y*BLOCKSIZE)+(i+(x*BLOCKSIZE))*size] = bmat[x][y][j +i*BLOCKSIZE];                                }                        }                }        }	fprintf(stderr, "compute explicit LLt ...\n");	for (j = 0; j < size; j++)	{		for (i = 0; i < size; i++)		{			if (i > j) {				rmat[j+i*size] = 0.0f; // debug			}		}	}	float test_mat[size * size] __heap;	STARPU_SSYRK("L", "N", size, size, 1.0f,	      rmat, size, 0.0f, test_mat, size);	fprintf(stderr, "comparing results ...\n");        if (display) {                for (j = 0; j < size; j++)		{                        for (i = 0; i < size; i++)			{                                if (i <= j) {                                        printf("%2.2f\t", test_mat[j +i*size]);                                }                                else {                                        printf(".\t");                                }                        }                        printf("\n");                }        }	int correctness = 1;        for(x = 0; x < nblocks ;  x++)	{                for (y = 0; y < nblocks; y++)		{			for (i = (size/nblocks)*x ; i < (size/nblocks)*x+(size/nblocks); i++)                                {                                        for (j = (size/nblocks)*y ; j < (size/nblocks)*y+(size/nblocks); j++)						{							if (i <= j)								{									float orig = (1.0f/(1.0f+i+j)) + ((i == j)?1.0f*size:0.0f);									float err = abs(test_mat[j +i*size] - orig);									if (err > 0.00001) {										fprintf(stderr, "Error[%u, %u] --> %2.2f != %2.2f (err %2.2f)\n", i, j, test_mat[j +i*size], orig, err);										correctness = 0;										break;									}								}						}                                }		}        }        starpu_cublas_shutdown();#pragma starpu shutdown	assert(correctness);	return 0;}
 |