Добрый день !
Хочу написать простейшую работающую программу на ptx-ассемблере.
Для начала, написал основную программу (cuTest.cpp), которая передает в вызываемое вычислительное ядро массив,
проинициализированный значением -1:
#include "stdio.h" #include "malloc.h" #include "cuda.h" #include "cuda_runtime_api.h" #define ALIGN_UP(offset, alignment) (offset) = ((offset) + (alignment) - 1) & ~((alignment) - 1) int main ( int argc , char** argv ) { int rt_version; int N = 8; int nDevice = atoi ( argv [ 1 ] ); printf ( "Device number = %d\n", nDevice ); char* file_name = argv [ 2 ]; char* func_name = argv [ 3 ]; CUresult result = cuInit(0); int deviceCount = 0; cuDeviceGetCount ( &deviceCount ); printf ( "deviceCount = %d\n", deviceCount ); CUdevice cuDevice = 0; cuDeviceGet ( &cuDevice, nDevice ); CUcontext cuContext; cuCtxCreate ( &cuContext, 0, cuDevice ); cudaRuntimeGetVersion ( &rt_version ); printf ( "Runtime version = %d.%d\n", rt_version/1000, rt_version%100 ); int* A = (int*) malloc ( N * sizeof ( int ) ); for ( int i = 0; i < N; i++ ) A [ i ] = -1; printf ( "Before ->\n" ); for ( int i = 0; i < N; i++ ) printf ( "%d\n", A [ i ] ); CUdeviceptr dA = cuMemAlloc ( &dA, N * sizeof ( int ) ); cuMemcpyHtoD(dA, A, N * sizeof ( int ) ); CUmodule cuModule; result = cuModuleLoad ( &cuModule, file_name ); printf ( "ModuleLoad result = %d\n", result ); CUfunction cuFunc; result = cuModuleGetFunction ( &cuFunc, cuModule, func_name ); printf ( "GetFunction result = %d\n", result ); int offset = 0; void* ptr; ptr = (void*)(size_t)dA; ALIGN_UP(offset, __alignof(ptr)); result = cuParamSetv ( cuFunc, offset, &ptr, sizeof (ptr) ); printf ( "ParamSetv result = %d\n", result ); offset += sizeof(ptr); result = cuParamSetSize ( cuFunc, offset ); printf ( "ParamSetSize result = %d\n", result ); int threadsPerBlock = N; int blocksPerGrid = 1; result = cuFuncSetBlockShape ( cuFunc, threadsPerBlock, 1, 1); printf ( "FuncSetBlockShape result = %d\n", result ); result = cuLaunchGrid ( cuFunc, blocksPerGrid, 1 ); printf ( "LaunchGrid result = %d\n", result ); cuMemcpyDtoH( A, dA, N * sizeof ( int ) ); printf ( "After ->\n" ); for ( int i = 0; i < N; i++ ) printf ( "%d\n", A [ i ] ); }
Транслируется она обычным образом:
nvcc -L/usr/lib64 -lcuda -o cuTest cuTest.cpp
Затем написал простейший ptx-код (файл test.ptx, который лежит в одной директории с главной программой), который присваивает первому элементу массива (т.е., 0-му по номеру) значение 0:
.version 1.4 .target sm_10 .entry test ( .param .s32 C ) { .reg .s32 %p<1>; ld.param.s32 %p0, [C]; st.global.s32 [%p0], 0; ret; }
Запускаю и получаю :
./cuTest 1 test.ptx test Device number = 1 deviceCount = 2 Runtime version = 3.20 Before -> -1 -1 -1 -1 -1 -1 -1 -1 ModuleLoad result = 0 GetFunction result = 0 ParamSetv result = 0 ParamSetSize result = 0 FuncSetBlockShape result = 0 LaunchGrid result = 0 After -> -1 -1 -1 -1 -1 -1 -1 -1
Т.е., программа, вроде бы отрабатывает, но никаких изменений в массиве не происходит.
Более того, если в основной программе закомментировать часть, связанную с передачей параметров,
а именно
/* int offset = 0; void* ptr; ptr = (void*)(size_t)dA; ALIGN_UP(offset, __alignof(ptr)); result = cuParamSetv ( cuFunc, offset, &ptr, sizeof (ptr) ); printf ( "ParamSetv result = %d\n", result ); offset += sizeof(ptr); result = cuParamSetSize ( cuFunc, offset ); printf ( "ParamSetSize result = %d\n", result ); */
результат получается точно такой же -
т.е., похоже, что ptx-функция "не видит" входных параметров.
Есть ли у кого-нибудь успешный опыт написания своих ptx-программ,
и в чём тут может быть дело ?
Спасибо.