代码之家  ›  专栏  ›  技术社区  ›  cfuqua

使用驱动程序API创建纹理对象时发生JCuda访问冲突

  •  0
  • cfuqua  · 技术社区  · 8 年前

    我有一个JCuda项目,每当它尝试使用驱动程序API创建纹理对象时,都会遇到访问冲突。Java HotSpot声称错误来自nvcuda。dll。

    从中创建纹理的基础CUarray似乎已正确填充;将其内容复制回主机端浮点数组将生成与初始主机端数据相同的数组。这意味着错误本身必须是纹理声明中的某个内容,对吗?

    使用cuda memcheck运行代码不会显示任何错误。

    以下是遇到错误的代码:

    import jcuda.Pointer;
    import jcuda.Sizeof;
    import jcuda.driver.*;
    
    public class Main {
    
        public static void main(String[] args) {
            init();
    
            float[] hostArray = new float[]{0, 1, 2, 3, 4, 5, 6, 7};
            int[] dims = new int[]{2,2,2};
    
            CUdeviceptr deviceArray = new CUdeviceptr();
            JCudaDriver.cuMemAlloc(deviceArray, hostArray.length * Sizeof.FLOAT);
            JCudaDriver.cuMemcpyHtoD(deviceArray, Pointer.to(hostArray), hostArray.length * Sizeof.FLOAT);
    
            // initialize the opaque array object to represent the texture's data
            CUarray cuArray = makeCudaArray(dims);
    
            // populate the opaque array object
            copyDataIntoCudaArray(deviceArray, cuArray, dims);
    
            JCudaDriver.cuMemFree(deviceArray);
    
            // create the various descriptors
            CUDA_RESOURCE_DESC resourceDescriptor = makeResourceDescriptor(cuArray);
            CUDA_TEXTURE_DESC textureDescriptor = makeTextureDescriptor();
            CUDA_RESOURCE_VIEW_DESC resourceViewDescriptor = makeResourceViewDescriptor(dims);
    
            CUtexObject texture = new CUtexObject();
    
            System.out.println("About to hit an access violation:");
            JCudaDriver.cuTexObjectCreate(texture, resourceDescriptor, textureDescriptor, resourceViewDescriptor);
        }
    
        static void init() {
            JCudaDriver.setExceptionsEnabled(true);
            JCudaDriver.cuInit(0);
    
            int[] deviceCount = new int[1];
            JCudaDriver.cuDeviceGetCount(deviceCount);
    
            CUdevice currentDevice = new CUdevice();
            JCudaDriver.cuDeviceGet(currentDevice, 0);
    
            CUcontext currentContext = new CUcontext();
            JCudaDriver.cuCtxCreate(currentContext, 0, currentDevice);
        }
    
        static CUarray makeCudaArray(int[] dims) {
            CUarray array = new CUarray();
            CUDA_ARRAY3D_DESCRIPTOR arrayDescriptor = new CUDA_ARRAY3D_DESCRIPTOR();
    
            arrayDescriptor.Width = dims[0];
            arrayDescriptor.Height = dims[1];
            arrayDescriptor.Depth = dims[2];
            arrayDescriptor.Format = CUarray_format.CU_AD_FORMAT_FLOAT;
            arrayDescriptor.NumChannels = 1;
            arrayDescriptor.Flags = 0;
    
            JCudaDriver.cuArray3DCreate(array, arrayDescriptor);
            return array;
        }
    
        static void copyDataIntoCudaArray(CUdeviceptr deviceArray, CUarray array, int[] dims) {
            CUDA_MEMCPY3D copyParams = new CUDA_MEMCPY3D();
            copyParams.srcMemoryType = CUmemorytype.CU_MEMORYTYPE_DEVICE;
            copyParams.srcDevice = deviceArray;
            copyParams.srcXInBytes = 0;
            copyParams.srcY = 0;
            copyParams.srcZ = 0;
            copyParams.srcPitch = (long) dims[0] * Sizeof.FLOAT;
            copyParams.srcHeight = dims[1];
            copyParams.srcLOD = 0;
    
            copyParams.dstMemoryType = CUmemorytype.CU_MEMORYTYPE_ARRAY;
            copyParams.dstArray = array;
            copyParams.dstXInBytes = 0;
            copyParams.dstY = 0;
            copyParams.dstZ = 0;
            copyParams.dstLOD = 0;
    
            copyParams.WidthInBytes = (long) dims[0] * Sizeof.FLOAT;
            copyParams.Height = dims[1];
            copyParams.Depth = dims[2];
    
            JCudaDriver.cuMemcpy3D(copyParams);
        }
    
        static CUDA_RESOURCE_DESC makeResourceDescriptor(CUarray cuArray) {
            CUDA_RESOURCE_DESC resourceDescriptor = new CUDA_RESOURCE_DESC();
            resourceDescriptor.resType = CUresourcetype.CU_RESOURCE_TYPE_ARRAY;
            resourceDescriptor.array_hArray = cuArray;
            resourceDescriptor.flags = 0;
            return resourceDescriptor;
        }
    
        static CUDA_TEXTURE_DESC makeTextureDescriptor() {
            CUDA_TEXTURE_DESC textureDescriptor = new CUDA_TEXTURE_DESC();
            textureDescriptor.addressMode = new int[]{
                    CUaddress_mode.CU_TR_ADDRESS_MODE_CLAMP,
                    CUaddress_mode.CU_TR_ADDRESS_MODE_CLAMP,
                    CUaddress_mode.CU_TR_ADDRESS_MODE_CLAMP };
            textureDescriptor.filterMode = CUfilter_mode.CU_TR_FILTER_MODE_LINEAR;
            textureDescriptor.flags = 0;
            textureDescriptor.maxAnisotropy = 1;
            textureDescriptor.mipmapFilterMode = CUfilter_mode.CU_TR_FILTER_MODE_POINT;
            textureDescriptor.mipmapLevelBias = 0;
            textureDescriptor.minMipmapLevelClamp = 0;
            textureDescriptor.maxMipmapLevelClamp = 0;
            return textureDescriptor;
        }
    
        static CUDA_RESOURCE_VIEW_DESC makeResourceViewDescriptor(int[] dims) {
            CUDA_RESOURCE_VIEW_DESC resourceViewDescriptor = new CUDA_RESOURCE_VIEW_DESC();
            resourceViewDescriptor.format = CUresourceViewFormat.CU_RES_VIEW_FORMAT_FLOAT_1X32;
            resourceViewDescriptor.width = dims[0];
            resourceViewDescriptor.height = dims[1];
            resourceViewDescriptor.depth = dims[2];
            resourceViewDescriptor.firstMipmapLevel = 0;
            resourceViewDescriptor.lastMipmapLevel = 0;
            resourceViewDescriptor.firstLayer = 0;
            resourceViewDescriptor.lastLayer = 0;
            return resourceViewDescriptor;
        }
    }
    

    我做错了什么?

    1 回复  |  直到 4 年前
        1
  •  1
  •   Marco13    8 年前

    此访问冲突的原因是JCuda 0.9.0中的一个错误。

    纹理句柄作为 NULL 指针。这是固定的 this commit ,该修复程序将作为下一版本的一部分。

    A. test case based on the code in the question 已添加。

    更新: 此问题已在中修复 JCuda 0.9.0d .