我正在尝试使用 OPENCL 和 C 计算两个 matrix 的乘积:`
#include <CL/cl.h>
# include <stdio.h>
# include <math.h>
# include <assert.h>
# include <sys/stat.h>
char* lire_fichier_source ( const char *nom_fichier )
{
// On determine la taille du fichier .
struct stat st ;
stat ( nom_fichier , &st );
// On ouvre et on lit le contenu du fichier .
FILE* fich = fopen ( nom_fichier , " r " );
assert ( fich != NULL );
char* programme = (char*) malloc(st.st_size +1);
fread ( programme, sizeof(char),st.st_size ,fich );
fclose ( fich );
// La chaine doit se terminer par ASCII 0.
programme [ st.st_size ]='\0';
return programme ;
}
# define PRECISION 0.01
void initialiser ( float *a , size_t N )
{
int k = 0;
for ( int i = 0; i < N ; i++) {
for ( int j = 0; j < N ; j++) {
a[ i*N + j ] = 1;
}
}
}
void imprimer ( const char *nom , float *a , size_t N )
{
printf("%s::\n", nom );
for ( int i = 0; i < N ; i++) {
for ( int j = 0; j < N ; j++) {
printf ( " %f ", a [ i*N + j ] );
}
printf ("\n ");
}
}
int main (int argc, char** argv )
{
printf("j'ai entrée");
// On lit l’argument du programme , qui indique la taille
// des matrices a generer et multiplier .
assert( argc >= 2 );
size_t N = atoi(argv[1]);
//size_t N=4;
// On obtient un * device * de type GPU .
cl_platform_id plateforme ;
clGetPlatformIDs (1, &plateforme,NULL );
cl_device_id device ;
clGetDeviceIDs ( plateforme , CL_DEVICE_TYPE_CPU , 1 , &device , NULL );
printf("je suis dans 1");
// On cree un contexte et une queue d’execution .
cl_context contexte = clCreateContext ( NULL , 1 , &device , NULL , NULL , NULL );
printf("je suis dans 2");
cl_command_queue queue = clCreateCommandQueueWithProperties( contexte , device , 0 , NULL );
printf("je suis dans 3");
char *source = lire_fichier_source ( "produit_matrices.cl" );
printf("je suis dans4");
cl_program programme = clCreateProgramWithSource ( contexte , 1 ,( const char**)&source,NULL , NULL );
free ( source );
// REMARQUE : Si le code du kernel contient une erreur
// de compilation , c ’ est clBuildProgram qui retourne
// un resultat indiquant une erreur . Donc , en general ,
// il est crucial de verifier le code retourne .
clBuildProgram ( programme , 0 , NULL , NULL , NULL , NULL );
cl_kernel kernel=clCreateKernel ( programme , " produit_matrices " , NULL );
float a[ N*N ],b[ N*N ];
initialiser ( a , N );
initialiser ( b , N );
cl_mem buffer_a=clCreateBuffer(contexte,CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR ,sizeof( float )*N*N , a , NULL );
cl_mem buffer_b =clCreateBuffer( contexte ,CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR ,sizeof( float )*N*N , b , NULL );
cl_mem buffer_c = clCreateBuffer( contexte , CL_MEM_WRITE_ONLY ,sizeof( float )*N*N , NULL , NULL );
// On specifie les arguments du kernel et on lance son execution .
clSetKernelArg( kernel , 0 , sizeof( cl_mem ) , &buffer_a );
clSetKernelArg( kernel , 1 , sizeof( cl_mem ) , &buffer_b );
clSetKernelArg( kernel , 2 , sizeof( cl_mem ) , &buffer_c );
clSetKernelArg( kernel , 3 , sizeof( int ) , &N );
size_t nb_taches[]={N,N};
clEnqueueNDRangeKernel( queue , kernel , 2 , NULL , nb_taches ,NULL , 0 , NULL , NULL );
// On va chercher le resultat : CL_TRUE = > bloquant !
float c[N*N];
clEnqueueReadBuffer( queue , buffer_c , CL_TRUE , 0 ,sizeof( float )*N*N , c , 0 , NULL , NULL );
for ( int i = 0; i < N ; i ++ ) {
for ( int j = 0; j < N ; j ++ ) {
if ( fabsf( c [ i*N+j]-(1.0*N ))>PRECISION ) {
printf("*** Erreur : resultat incorrect [%d , %d ]: %f\n" ,i , j , c[i*N+j]);
exit( -1 );
}
}
}
clReleaseMemObject( buffer_a );
clReleaseMemObject( buffer_b );
clReleaseMemObject( buffer_c );
clReleaseKernel(kernel );
clReleaseProgram(programme );
clReleaseCommandQueue(queue );
clReleaseContext(contexte );
return 0;
}
这是程序的内核:
__kernel void produit_matrices ( __global const float* a ,
__global const float* b ,
__global float* c ,
uint N )
{
int i = get_global_id (0);
int j = get_global_id (1);
float total = 0.0;
for ( int k = 0; k<N ; k++ ) {
total += a [i*N+k]*b[k*N+j];
}
c[i*N+j]=total ;
}
请如果有人有 OpenCL 感谢执行它,因为它总是给我“0”
在运行 C 程序时,我收到以下错误,我似乎无法弄清楚原因。我已经尝试了所有谷歌解决方案但不起作用
opencl:produits_matrices.c:49: main: 断言 'argc >= 2' 失败。放弃(核心转储)
回答1
正如 SidoShiro92 在他的评论中指出的那样,您的可执行文件希望您在控制台中输入一个整数作为参数,例如 ./opencl 5
。否则 assert
将抛出运行时错误。