Форум Академгородка, Новосибирск > Intel C + Nvidia C + gFortran
Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Intel C + Nvidia C + gFortran
Форум Академгородка, Новосибирск > Компьютеры и сети > Программирование
Texnik
Доброго времени суток, форумчане!

Имеется необходимость склеить три части программы написанных на C (для Intel C компилятора), CUDA C и Fortran (пойдет любой, но в данный момент экспериментирую с gFortran). Часть написанная на Fortran - головная, остальные написаны для быстрого выполнения определенных задач на процессоре и видео карте. Само склеивание прошло достаточно успешно, все три подрограммы запускаются, однако есть проблема с частью написанной для GPU: она запускается, видит наличие CUDA GPU, но ничего не вычисляет.

Результат запуска:
CODE

Result by gFortran
1.133 1.284 1.455 1.649 1.868 2.117 2.399 2.718
Result by Intel C (using SVML)
1.133 1.284 1.455 1.649 1.868 2.117 2.399 2.718

Begin CUDA Driver
There are 1 CUDA devices.
Name of CUDA GPU # 0: Quadro FX 570

CUDA error (malloc d_X) = no error
CUDA error (malloc d_Y) = no error
CUDA error (copy d_X) = no error
CUDA error (memset d_Y) = no error
CUDA error (copyback d_Y) = no error
End CUDA Driver

Result by CUDA
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000


Вопрос: Почему, на вид, работающая CUDA подпрограмма не дает правильный результат? Скорее всего ошибка глупая, понять где именно никак не могу.

Ниже приведен текст программы:
Головная часть на Fortran(fortcode.f90):
CODE

program expVec
use, intrinsic :: iso_c_binding
interface
subroutine cfunc(X,Y,N) bind ©
use, intrinsic :: iso_c_binding
integer ( c_int ), value :: N
real (c_float) :: X(*), Y(*)
end subroutine cfunc
subroutine cudadriver(X,Y,N) bind (C, name="cudadriver")
use, intrinsic :: iso_c_binding
integer ( c_int ), value :: N
real (c_float) :: X(*), Y(*)
end subroutine cudadriver
end interface

integer (c_int), parameter:: N = 8
integer (c_int) :: a,b, res
real (c_float):: X(N), Y(N)
real(8)::localres

do i=1,N
X(i) = i*0.125E0
Y(i) = exp(X(i))
enddo

write(*,*)"Result by gFortran"
write(*,'(16F8.3)'),Y(smile.gif

Y(smile.gif = 0.E0
call cfunc(X,Y,N)
write(*,*)"Result by Intel C (using SVML)"
write(*,'(16F8.3)'),Y(smile.gif

Y(smile.gif = 1.E0
call cudadriver(X,Y,N)
write(*,*)"Result by CUDA"
write(*,'(16F8.3)'),Y(smile.gif
end program

Часть для С (ccode.c):
CODE
#include <stdio.h>
#include <math.h>
#include <immintrin.h>
void cfunc(float *X, float *Y, int N)
{
int i;
__m128 xmm0;
for (i = 0;i < N;i+=4) {
xmm0 = _mm_load_ps(&X[i]);
xmm0 = _mm_exp_ps(xmm0);
_mm_store_ps(&Y[i], xmm0);
}
}

Часть для CUDA GPU(gpucode.cu):
CODE
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <cuda.h>


__global__ void devicefunc(float* X, float* Y, int N)
{

int i = blockDim.x*blockIdx.x + threadIdx.x;
if (i < N){
Y[i] = exp(X[i]);
}

}


extern "C"
{
void cudadriver(float* X, float* Y, int N)
{
float* d_X;
float* d_Y;
size_t size = N*sizeof(float);
cudaError_t Error;
int i;
int devCount;
cudaDeviceProp devProp;

printf("\n\tBegin CUDA Driver\n");

cudaGetDeviceCount(&devCount);
printf("\t\tThere are %d CUDA devices.\n", devCount);

for (i = 0; i < devCount; i++) {
cudaGetDeviceProperties(&devProp, i);
printf("\t\tName of CUDA GPU # %d: %s\n",i, devProp.name);
}

Error = cudaMalloc((void**)&d_X, size);
printf("\n\t\tCUDA error (malloc d_X) = \t%s\n",cudaGetErrorString(Error));
Error = cudaMalloc((void**)&d_Y, size);
printf("\t\tCUDA error (malloc d_Y) = \t%s\n",cudaGetErrorString(Error));

Error = cudaMemcpy(d_X, X, size, cudaMemcpyHostToDevice);
printf("\t\tCUDA error (copy d_X) = \t%s\n",cudaGetErrorString(Error));

Error = cudaMemset(d_Y, 3.E0, size);
printf("\t\tCUDA error (memset d_Y) = \t%s\n",cudaGetErrorString(Error));

devicefunc<<<N/8+1,8>>>(d_X, d_Y, N);

Error = cudaMemcpy(Y, d_Y, size, cudaMemcpyDeviceToHost);
printf("\t\tCUDA error (copyback d_Y) = \t%s\n",cudaGetErrorString(Error));

printf("\tEnd CUDA Driver\n\n");

cudaFree(d_X);
cudaFree(d_Y);
}
}

Содержимое Makefile:
CODE
CFLAGS= -O3
DEPS =
OBJ = ccode.o gpucode.o fortcode.o
LIBS = -L/usr/local/cuda/lib64 -lcudart

%.o: %.c $(DEPS)
icc -c -o $@ $< $(CFLAGS) -lsvml -msse
%.o: %.f90
gfortran -c -o $@ $< $(CFLAGS)
%.o: %.cu
nvcc -c -o $@ $< -arch=sm_12 $(CFLAGS) $(LIBS)

fort_c: $(OBJ)
gfortran -o $@ $^ $(CFLAGS) -lsvml $(LIBS)

clean:
rm -f *.o fort_c
Texnik
Nox Metus, большое спасибо за совет smile.gif Выяслилось, что дело в видеокарте sad.gif запустил на другом железе - все плошло, потом еще погонял тесты из стандартного пакета - часть на ней не пошла sad.gif еще неделю назад работала.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Русская версия IP.Board © 2001-2024 IPS, Inc.