8000 Preserve device offsets in driver resource descriptors by RicheyWorks · Pull Request #56 · jcuda/jcuda · GitHub
[go: up one dir, main page]

Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions JCudaDriverJNI/src/JCudaDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1288,15 +1288,15 @@ CUDA_RESOURCE_DESC getCUDA_RESOURCE_DESC(JNIEnv *env, jobject resourceDesc)

case CU_RESOURCE_TYPE_LINEAR:
linear_devPtr = env->GetObjectField(resourceDesc, CUDA_RESOURCE_DESC_linear_devPtr);
nativeResourceDesc.res.linear.devPtr = (CUdeviceptr)getNativePointerValue(env, linear_devPtr);
nativeResourceDesc.res.linear.devPtr = (CUdeviceptr)getPointer(env, linear_devPtr);
nativeResourceDesc.res.linear.format = (CUarray_format)env->GetIntField(resourceDesc, CUDA_RESOURCE_DESC_linear_format);
nativeResourceDesc.res.linear.numChannels = (unsigned int)env->GetIntField(resourceDesc, CUDA_RESOURCE_DESC_linear_numChannels);
nativeResourceDesc.res.linear.sizeInBytes = (size_t)env->GetLongField(resourceDesc, CUDA_RESOURCE_DESC_linear_sizeInBytes);
break;

case CU_RESOURCE_TYPE_PITCH2D:
pitch2D_devPtr = env->GetObjectField(resourceDesc, CUDA_RESOURCE_DESC_pitch2D_devPtr);
nativeResourceDesc.res.pitch2D.devPtr = (CUdeviceptr)getNativePointerValue(env, pitch2D_devPtr);
nativeResourceDesc.res.pitch2D.devPtr = (CUdeviceptr)getPointer(env, pitch2D_devPtr);
nativeResourceDesc.res.pitch2D.format = (CUarray_format)env->GetIntField(resourceDesc, CUDA_RESOURCE_DESC_pitch2D_format);
nativeResourceDesc.res.pitch2D.numChannels = (unsigned int)env->GetIntField(resourceDesc, CUDA_RESOURCE_DESC_pitch2D_numChannels);
nativeResourceDesc.res.pitch2D.width = (size_t)env->GetLongField(resourceDesc, CUDA_RESOURCE_DESC_pitch2D_width);
Expand Down Expand Up @@ -1335,15 +1335,15 @@ void setCUDA_RESOURCE_DESC(JNIEnv *env, jobject resourceDesc, CUDA_RESOURCE_DESC

case CU_RESOURCE_TYPE_LINEAR:
linear_devPtr = env->GetObjectField(resourceDesc, CUDA_RESOURCE_DESC_linear_devPtr);
setNativePointerValue(env, linear_devPtr, (jlong)nativeResourceDesc.res.linear.devPtr);
setPointer(env, linear_devPtr, (jlong)nativeResourceDesc.res.linear.devPtr);
env->SetIntField(resourceDesc, CUDA_RESOURCE_DESC_linear_format, (jint)nativeResourceDesc.res.linear.format);
env->SetIntField(resourceDesc, CUDA_RESOURCE_DESC_linear_numChannels, (jint)nativeResourceDesc.res.linear.numChannels);
env->SetLongField(resourceDesc, CUDA_RESOURCE_DESC_linear_sizeInBytes, (jlong)nativeResourceDesc.res.linear.sizeInBytes);
break;

case CU_RESOURCE_TYPE_PITCH2D:
pitch2D_devPtr = env->GetObjectField(resourceDesc, CUDA_RESOURCE_DESC_pitch2D_devPtr);
setNativePointerValue(env, pitch2D_devPtr, (jlong)nativeResourceDesc.res.pitch2D.devPtr);
setPointer(env, pitch2D_devPtr, (jlong)nativeResourceDesc.res.pitch2D.devPtr);
env->SetIntField(resourceDesc, CUDA_RESOURCE_DESC_pitch2D_format, (jint)nativeResourceDesc.res.pitch2D.format);
env->SetIntField(resourceDesc, CUDA_RESOURCE_DESC_pitch2D_numChannels, (jint)nativeResourceDesc.res.pitch2D.numChannels);
env->SetLongField(resourceDesc, CUDA_RESOURCE_DESC_pitch2D_width, (jlong)nativeResourceDesc.res.pitch2D.width);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/*
* JCuda - Java bindings for CUDA
*
* http://www.jcuda.org
*/
package jcuda.test;

import static jcuda.driver.JCudaDriver.*;
import static jcuda.driver.CUresult.CUDA_SUCCESS;
import static org.junit.Assert.assertEquals;

import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

import jcuda.Pointer;
import jcuda.driver.*;

/** Queries the actual address bound by driver texture descriptors. */
@RunWith(Parameterized.class)
public class JCudaDriverResourcePointerOffsetTest
{
@Parameters(name = "pitch2D={0}, reuse={1}, shifted={2}")
public static Collection<Object[]> cases()
{
Collection<Object[]> result = new ArrayList<Object[]>();
for (boolean pitched : new boolean[] { false, true })
for (boolean reuse : new boolean[] { false, true })
for (boolean shifted : new boolean[] { false, true })
result.add(new Object[] { pitched, reuse, shifted });
return result;
}

private final boolean pitched, reuse, shifted;

public JCudaDriverResourcePointerOffsetTest(boolean pitched, boolean reuse, boolean shifted)
{
this.pitched = pitched;
this.reuse = reuse;
this.shifted = shifted;
}

private static class InspectablePointer extends Pointer
{
InspectablePointer(Pointer pointer) { super(pointer); }
long address() { return getNativePointer() + getByteOffset(); }
}

@Test
public void testResourcePointerRoundTrip() throws Exception
{
ExecutorService executor = Executors.newSingleThreadExecutor();
try
{
executor.submit(new Callable<Void>()
{
@Override
public Void call()
{
roundTrip();
return null;
}
}).get();
}
finally { executor.shutdown(); }
}

private void roundTrip()
{
assertEquals(CUDA_SUCCESS, cuInit(0));
CUdevice device = new CUdevice();
assertEquals(CUDA_SUCCESS, cuDeviceGet(device, 0));
int[] alignment = { 0 }, pitchAlignment = { 0 };
assertEquals(CUDA_SUCCESS, cuDeviceGetAttribute(alignment,
CUdevice_attribute.CU_DEVICE_ATTRIBUTE_TEXTURE_ALIGNMENT, device));
assertEquals(CUDA_SUCCESS, cuDeviceGetAttribute(pitchAlignment,
CUdevice_attribute.CU_DEVICE_ATTRIBUTE_TEXTURE_PITCH_ALIGNMENT, device));
long pitch = ((16L + pitchAlignment[0] - 1) / pitchAlignment[0]) * pitchAlignment[0];
CUcontext context = new CUcontext();
assertEquals(CUDA_SUCCESS, cuCtxCreate(context, 0, device));
try
{
CUdeviceptr allocation = new CUdeviceptr();
assertEquals(CUDA_SUCCESS, cuMemAlloc(allocation, 2L * alignment[0] + 2L * pitch));
try
{
long address = new InspectablePointer(allocation).address();
long offset = shifted ? Math.floorMod(-address, (long)alignment[0]) + alignment[0] : 0;
CUdeviceptr pointer = allocation.withByteOffset(offset);
long expected = new InspectablePointer(pointer).address();
driverRoundTrip(pointer, expected, pitch);
}
finally { assertEquals(CUDA_SUCCESS, cuMemFree(allocation)); }
}
finally { assertEquals(CUDA_SUCCESS, cuCtxDestroy(context)); }
}

private void driverRoundTrip(CUdeviceptr pointer, long expected, long pitch)
{
CUDA_RESOURCE_DESC source = new CUDA_RESOURCE_DESC();
if (pitched)
{
source.resType = CUresourcetype.CU_RESOURCE_TYPE_PITCH2D;
source.pitch2D_devPtr = pointer;
source.pitch2D_format = CUarray_format.CU_AD_FORMAT_FLOAT;
source.pitch2D_numChannels = 1;
source.pitch2D_width = 4;
source.pitch2D_height = 2;
source.pitch2D_pitchInBytes = pitch;
}
else
{
source.resType = CUresourcetype.CU_RESOURCE_TYPE_LINEAR;
source.linear_devPtr = pointer;
source.linear_format = CUarray_format.CU_AD_FORMAT_FLOAT;
source.linear_numChannels = 1;
source.linear_sizeInBytes = 16;
}
CUDA_TEXTURE_DESC textureDesc = new CUDA_TEXTURE_DESC();
for (int i = 0; i < 3; i++) textureDesc.addressMode[i] = CUaddress_mode.CU_TR_ADDRESS_MODE_CLAMP;
textureDesc.filterMode = CUfilter_mode.CU_TR_FILTER_MODE_POINT;
textureDesc.maxAnisotropy = 1;
CUtexObject texture = new CUtexObject();
assertEquals(CUDA_SUCCESS, cuTexObjectCreate(texture, source, textureDesc, null));
try
{
CUDA_RESOURCE_DESC result = new CUDA_RESOURCE_DESC();
assertEquals(CUDA_SUCCESS, cuTexObjectGetResourceDesc(result, texture));
Pointer actual = pitched ? result.pitch2D_devPtr : result.linear_devPtr;
assertEquals(expected, new InspectablePointer(actual).address());
if (reuse)
{
assertEquals(CUDA_SUCCESS, cuTexObjectGetResourceDesc(source, texture));
Pointer reused = pitched ? source.pitch2D_devPtr : source.linear_devPtr;
assertEquals(expected, new InspectablePointer(reused).address());
}
}
finally { assertEquals(CUDA_SUCCESS, cuTexObjectDestroy(texture)); }
}

}
0