471,354 Members | 1,781 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,354 software developers and data experts.

Memory corruption with interop call

First of all, I apologize for cross-posting. I posted this on the
framework.interop group as well, but haven't received a response yet, so I
thought I'd try here...

I'm trying to write an app that perfroms some work using the CUDA SDK (for
programming the nVidia GPU).

One of the first methods I wrote is simply to query information about the
CUDA devices (video cards).

The code is very straightforward, but I'm getting an error that indicates
some sort of memory corruption and I'm not really sure how it's happening. I
don't think it's CUDA related, I think it's just something wrong with my
interop calls. Maybe the arrays? The exception I'm getting happens during
the return from GetCUDADeviceProperties (see implementation below and
comment on line that throws exception). It appears to be happening in the
marshalling back of the data. The exception is:

"An unhandled exception of type 'System.AccessViolationException' occurred
in NeuralNetTimingTest.exe
Additional information: Attempted to read or write protected memory. This is
often an indication that other memory is corrupt."

When I step through the code, GetCUDADeviceProperties() appears to properly
set the fields in the CUDADevice structure.

Here's the relevant code:

From C#:

* The device information structure is this:

[StructLayout(LayoutKind.Sequential)]
public struct CUDADevice
{
public int deviceID;
public int totalMem;
public int numMultiProcessors;
public int numCores;
public int constantMem;
public int sharedMem;
public int registersPerBlock;
public int warpSize;
public int numThreadsPerBlock;
public int[] maxBlockDimensions;
public int[] maxGridDimensions;
}

* The DllImport is:

[DllImport("NeuralNetCUDALib")]
extern static bool GetCUDADeviceProperties(ref CUDADevice device);

* And the C# code that calls it is:

// Allocate the device structure
CUDADevice dev = new CUDADevice();
// Allocate the two arrays
dev.maxBlockDimensions = new int[3];
dev.maxGridDimensions = new int[3];

// Device to query
dev.deviceID = 0;
GetCUDADeviceProperties(ref dev);

* The non-CUDA C++ code is:
* From the .h, the C++ side of the CUDADevice structure

typedef struct tagCUDADevice
{
int deviceID;
int totalMem;
int numMultiProcessors;
int numCores;
int constantMem;
int sharedMem;
int registersPerBlock;
int warpSize;
int numThreadsPerBlock;
int maxBlockDimensions[3];
int maxGridDimensions[3];
} CUDADevice;

extern "C" bool GetCUDADeviceProperties(CUDADevice *pDevice)
{
if (GetDeviceCount() <= 0)
{
return false;
}

if (!QueryDeviceInfo(pDevice->deviceID,
pDevice->totalMem,
pDevice->numMultiProcessors,
pDevice->numCores,
pDevice->constantMem,
pDevice->sharedMem,
pDevice->registersPerBlock,
pDevice->warpSize,
pDevice->numThreadsPerBlock,
pDevice->maxBlockDimensions,
pDevice->maxGridDimensions))
{
return false;
}
return true; // Exception happens during this return!
}
* And the actual CUDA code is:

bool QueryDeviceInfo(int deviceNum,
int &totalMem,
int &numMultiProcessors,
int &numCores,
int &constantMem,
int &sharedMem,
int &registersPerBlock,
int &warpSize,
int &numThreadsPerBlock,
int *maxBlockDimensions,
int *maxGridDimensions)
{
cudaDeviceProp prop;
cudaGetDeviceProperties(&prop, deviceNum);
totalMem = (int) prop.totalGlobalMem;
numMultiProcessors = (int) prop.multiProcessorCount;
numCores = (int) numMultiProcessors * 8;
constantMem = (int) prop.totalConstMem;
sharedMem = (int) prop.sharedMemPerBlock;
registersPerBlock = (int) prop.regsPerBlock;
warpSize = (int) prop.warpSize;
numThreadsPerBlock = (int) prop.maxThreadsPerBlock;
maxBlockDimensions[0] = (int) prop.maxThreadsDim[0];
maxBlockDimensions[1] = (int) prop.maxThreadsDim[1];
maxBlockDimensions[2] = (int) prop.maxThreadsDim[2];
maxGridDimensions[0] = (int) prop.maxGridSize[0];
maxGridDimensions[1] = (int) prop.maxGridSize[1];
maxGridDimensions[2] = (int) prop.maxGridSize[2];
return true;
}

Jul 28 '08 #1
2 3581
Fredo,

It looks like your declaration for the CUDADevice is incorrect. You
have to specify that the arrays are passed by value in the structure of the
array:

[StructLayout(LayoutKind.Sequential)]
public struct CUDADevice
{
public int deviceID;
public int totalMem;
public int numMultiProcessors;
public int numCores;
public int constantMem;
public int sharedMem;
public int registersPerBlock;
public int warpSize;
public int numThreadsPerBlock;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public int[] maxBlockDimensions;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public int[] maxGridDimensions;
}

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com
"Fredo" <fr***@hotmail.comwrote in message
news:_c******************************@giganews.com ...
First of all, I apologize for cross-posting. I posted this on the
framework.interop group as well, but haven't received a response yet, so I
thought I'd try here...

I'm trying to write an app that perfroms some work using the CUDA SDK (for
programming the nVidia GPU).

One of the first methods I wrote is simply to query information about the
CUDA devices (video cards).

The code is very straightforward, but I'm getting an error that indicates
some sort of memory corruption and I'm not really sure how it's happening.
I
don't think it's CUDA related, I think it's just something wrong with my
interop calls. Maybe the arrays? The exception I'm getting happens during
the return from GetCUDADeviceProperties (see implementation below and
comment on line that throws exception). It appears to be happening in the
marshalling back of the data. The exception is:

"An unhandled exception of type 'System.AccessViolationException' occurred
in NeuralNetTimingTest.exe
Additional information: Attempted to read or write protected memory. This
is
often an indication that other memory is corrupt."

When I step through the code, GetCUDADeviceProperties() appears to
properly
set the fields in the CUDADevice structure.

Here's the relevant code:

From C#:

* The device information structure is this:

[StructLayout(LayoutKind.Sequential)]
public struct CUDADevice
{
public int deviceID;
public int totalMem;
public int numMultiProcessors;
public int numCores;
public int constantMem;
public int sharedMem;
public int registersPerBlock;
public int warpSize;
public int numThreadsPerBlock;
public int[] maxBlockDimensions;
public int[] maxGridDimensions;
}

* The DllImport is:

[DllImport("NeuralNetCUDALib")]
extern static bool GetCUDADeviceProperties(ref CUDADevice device);

* And the C# code that calls it is:

// Allocate the device structure
CUDADevice dev = new CUDADevice();
// Allocate the two arrays
dev.maxBlockDimensions = new int[3];
dev.maxGridDimensions = new int[3];

// Device to query
dev.deviceID = 0;
GetCUDADeviceProperties(ref dev);

* The non-CUDA C++ code is:
* From the .h, the C++ side of the CUDADevice structure

typedef struct tagCUDADevice
{
int deviceID;
int totalMem;
int numMultiProcessors;
int numCores;
int constantMem;
int sharedMem;
int registersPerBlock;
int warpSize;
int numThreadsPerBlock;
int maxBlockDimensions[3];
int maxGridDimensions[3];
} CUDADevice;

extern "C" bool GetCUDADeviceProperties(CUDADevice *pDevice)
{
if (GetDeviceCount() <= 0)
{
return false;
}

if (!QueryDeviceInfo(pDevice->deviceID,
pDevice->totalMem,
pDevice->numMultiProcessors,
pDevice->numCores,
pDevice->constantMem,
pDevice->sharedMem,
pDevice->registersPerBlock,
pDevice->warpSize,
pDevice->numThreadsPerBlock,
pDevice->maxBlockDimensions,
pDevice->maxGridDimensions))
{
return false;
}
return true; // Exception happens during this return!
}
* And the actual CUDA code is:

bool QueryDeviceInfo(int deviceNum,
int &totalMem,
int &numMultiProcessors,
int &numCores,
int &constantMem,
int &sharedMem,
int &registersPerBlock,
int &warpSize,
int &numThreadsPerBlock,
int *maxBlockDimensions,
int *maxGridDimensions)
{
cudaDeviceProp prop;
cudaGetDeviceProperties(&prop, deviceNum);
totalMem = (int) prop.totalGlobalMem;
numMultiProcessors = (int) prop.multiProcessorCount;
numCores = (int) numMultiProcessors * 8;
constantMem = (int) prop.totalConstMem;
sharedMem = (int) prop.sharedMemPerBlock;
registersPerBlock = (int) prop.regsPerBlock;
warpSize = (int) prop.warpSize;
numThreadsPerBlock = (int) prop.maxThreadsPerBlock;
maxBlockDimensions[0] = (int) prop.maxThreadsDim[0];
maxBlockDimensions[1] = (int) prop.maxThreadsDim[1];
maxBlockDimensions[2] = (int) prop.maxThreadsDim[2];
maxGridDimensions[0] = (int) prop.maxGridSize[0];
maxGridDimensions[1] = (int) prop.maxGridSize[1];
maxGridDimensions[2] = (int) prop.maxGridSize[2];
return true;
}

Jul 28 '08 #2
You nailed it. Thanks Nicholas. Don't know what I'd do without you and
Jon....
"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.comwrote in
message news:OO**************@TK2MSFTNGP06.phx.gbl...
Fredo,

It looks like your declaration for the CUDADevice is incorrect. You
have to specify that the arrays are passed by value in the structure of
the array:

[StructLayout(LayoutKind.Sequential)]
public struct CUDADevice
{
public int deviceID;
public int totalMem;
public int numMultiProcessors;
public int numCores;
public int constantMem;
public int sharedMem;
public int registersPerBlock;
public int warpSize;
public int numThreadsPerBlock;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public int[] maxBlockDimensions;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public int[] maxGridDimensions;
}

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com
"Fredo" <fr***@hotmail.comwrote in message
news:_c******************************@giganews.com ...
>First of all, I apologize for cross-posting. I posted this on the
framework.interop group as well, but haven't received a response yet, so
I thought I'd try here...

I'm trying to write an app that perfroms some work using the CUDA SDK
(for
programming the nVidia GPU).

One of the first methods I wrote is simply to query information about the
CUDA devices (video cards).

The code is very straightforward, but I'm getting an error that indicates
some sort of memory corruption and I'm not really sure how it's
happening. I
don't think it's CUDA related, I think it's just something wrong with my
interop calls. Maybe the arrays? The exception I'm getting happens during
the return from GetCUDADeviceProperties (see implementation below and
comment on line that throws exception). It appears to be happening in the
marshalling back of the data. The exception is:

"An unhandled exception of type 'System.AccessViolationException'
occurred
in NeuralNetTimingTest.exe
Additional information: Attempted to read or write protected memory. This
is
often an indication that other memory is corrupt."

When I step through the code, GetCUDADeviceProperties() appears to
properly
set the fields in the CUDADevice structure.

Here's the relevant code:

From C#:

* The device information structure is this:

[StructLayout(LayoutKind.Sequential)]
public struct CUDADevice
{
public int deviceID;
public int totalMem;
public int numMultiProcessors;
public int numCores;
public int constantMem;
public int sharedMem;
public int registersPerBlock;
public int warpSize;
public int numThreadsPerBlock;
public int[] maxBlockDimensions;
public int[] maxGridDimensions;
}

* The DllImport is:

[DllImport("NeuralNetCUDALib")]
extern static bool GetCUDADeviceProperties(ref CUDADevice device);

* And the C# code that calls it is:

// Allocate the device structure
CUDADevice dev = new CUDADevice();
// Allocate the two arrays
dev.maxBlockDimensions = new int[3];
dev.maxGridDimensions = new int[3];

// Device to query
dev.deviceID = 0;
GetCUDADeviceProperties(ref dev);

* The non-CUDA C++ code is:
* From the .h, the C++ side of the CUDADevice structure

typedef struct tagCUDADevice
{
int deviceID;
int totalMem;
int numMultiProcessors;
int numCores;
int constantMem;
int sharedMem;
int registersPerBlock;
int warpSize;
int numThreadsPerBlock;
int maxBlockDimensions[3];
int maxGridDimensions[3];
} CUDADevice;

extern "C" bool GetCUDADeviceProperties(CUDADevice *pDevice)
{
if (GetDeviceCount() <= 0)
{
return false;
}

if (!QueryDeviceInfo(pDevice->deviceID,
pDevice->totalMem,
pDevice->numMultiProcessors,
pDevice->numCores,
pDevice->constantMem,
pDevice->sharedMem,
pDevice->registersPerBlock,
pDevice->warpSize,
pDevice->numThreadsPerBlock,
pDevice->maxBlockDimensions,
pDevice->maxGridDimensions))
{
return false;
}
return true; // Exception happens during this return!
}
* And the actual CUDA code is:

bool QueryDeviceInfo(int deviceNum,
int &totalMem,
int &numMultiProcessors,
int &numCores,
int &constantMem,
int &sharedMem,
int &registersPerBlock,
int &warpSize,
int &numThreadsPerBlock,
int *maxBlockDimensions,
int *maxGridDimensions)
{
cudaDeviceProp prop;
cudaGetDeviceProperties(&prop, deviceNum);
totalMem = (int) prop.totalGlobalMem;
numMultiProcessors = (int) prop.multiProcessorCount;
numCores = (int) numMultiProcessors * 8;
constantMem = (int) prop.totalConstMem;
sharedMem = (int) prop.sharedMemPerBlock;
registersPerBlock = (int) prop.regsPerBlock;
warpSize = (int) prop.warpSize;
numThreadsPerBlock = (int) prop.maxThreadsPerBlock;
maxBlockDimensions[0] = (int) prop.maxThreadsDim[0];
maxBlockDimensions[1] = (int) prop.maxThreadsDim[1];
maxBlockDimensions[2] = (int) prop.maxThreadsDim[2];
maxGridDimensions[0] = (int) prop.maxGridSize[0];
maxGridDimensions[1] = (int) prop.maxGridSize[1];
maxGridDimensions[2] = (int) prop.maxGridSize[2];
return true;
}


Jul 28 '08 #3

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Pete | last post: by
5 posts views Thread by Trokey | last post: by
5 posts views Thread by Noa Garnett | last post: by
10 posts views Thread by eyh5 | last post: by
8 posts views Thread by ranjeet.gupta | last post: by
14 posts views Thread by =?Utf-8?B?UHVjY2E=?= | last post: by
5 posts views Thread by John | last post: by
3 posts views Thread by not_a_commie | last post: by
66 posts views Thread by Why Tea | last post: by
reply views Thread by XIAOLAOHU | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.