Ядро ilgpu молча не компилируетсяC#

Место общения программистов C#
Ответить
Anonymous
 Ядро ilgpu молча не компилируется

Сообщение Anonymous »

Я пытаюсь отладить ядро, написанное для Ilgpu, которое не компилируется.
У моего привязки есть 2 больших ядра.
Первый (который загружается и делает правильные вещи): < /p>
///
/// Unified GPU kernel for processing multiple groups in a single batch call. Each thread
/// handles one (group, position) combination using BFS to determine reachability
///
private static void PurgeEquivalentManPositionsBatchKernel(
Index1D index,
ArrayView1D manPositions, // All man positions across all groups (padded)
ArrayView1D stateIndices, // Corresponding state indices for man positions
ArrayView1D diamondPositions, // Diamond positions grouped by group index
ArrayView1D groupSizes, // Number of valid positions per group
ArrayView2D layout, // Map layout (TileContent enum values)
int mapHeight,
int mapWidth,
int currentOrder, // Number of diamonds per group
int maxPositionsPerGroup, // Maximum positions in any group (for padding)
int totalGroups, // Total number of groups
ArrayView3D bfsWorkspace, // BFS workspace [thread][height][width]
ArrayView1D resultArray) // Output: 0=keep, 1=skip
{
// BOUNDS CHECK: Ensure we don't exceed the allocated array size
if (index >= manPositions.Length)
return;

// THREAD MAPPING: Convert linear thread index to (group, position) coordinates Each
// group has maxPositionsPerGroup slots (some may be padding)
int groupIndex = index / maxPositionsPerGroup; // Which group this thread handles
int positionIndex = index % maxPositionsPerGroup; // Which position within that group

// VALIDATION: Skip if this thread maps to invalid data This handles:
// - groupIndex beyond actual number of groups
// - positionIndex beyond actual positions in this group
// - stateIndices[index] == -1 (padding marker)
if (groupIndex >= totalGroups ||
positionIndex >= groupSizes[groupIndex] ||
stateIndices[index] < 0)
return;

// WORKSPACE INITIALIZATION: Set up the BFS grid for this thread Each thread gets its
// own slice of the 3D workspace: bfsWorkspace[index, *, *]
// Values: 0=free, 1=queued (current wavefront), 2=visited, 4=obstacle(wall/diamond)
for (int i = 0; i < mapHeight; i++)
{
for (int j = 0; j < mapWidth; j++)
{
// Check for Wall (2) or Outside (32) using TileContent enum values Wall |
// Outside = 2 | 32 = 34 (WallOrOutside)
if ((layout[i, j] & 34) != 0) // TileContent.WallOrOutside
bfsWorkspace[index, i, j] = 4; // Wall obstacle
else
bfsWorkspace[index, i, j] = 0; // Free space
}
}

// DIAMOND OBSTACLE PLACEMENT: Mark diamonds as impassable Diamond positions for this
// group start at (groupIndex * currentOrder)
int diamondOffset = groupIndex * currentOrder;
for (int d = 0; d < currentOrder; d++)
{
ushort diamondPos = diamondPositions[diamondOffset + d];

// DECODE POSITION: Extract row/col from packed ushort
// Format: high byte = row, low byte = col
byte row = (byte)(diamondPos >> 8);
byte col = (byte)(diamondPos & 0xFF);

// BOUNDS CHECK: Ensure diamond position is valid
if (row < mapHeight && col < mapWidth)
{
bfsWorkspace[index, row, col] = 4; // Diamond obstacle
}
}

// STARTING POSITION: Get the man position for this thread
ushort manPos = manPositions[index];
byte manRow = (byte)(manPos >> 8);
byte manCol = (byte)(manPos & 0xFF);

// BOUNDS CHECK: Ensure man position is valid
if (manRow >= mapHeight || manCol >= mapWidth)
return;

// BOUNDARY TRACKING
int minRow = manRow;
int maxRow = manRow;
int minCol = manCol;
int maxCol = manCol;

// BFS INITIALIZATION: Mark starting position as current wavefront
bfsWorkspace[index, manRow, manCol] = 1; // Mark as queued (current wavefront)

// DIRECTION VECTORS: Up, Right, Down, Left
int[] dr = [-1, 0, 1, 0];
int[] dc = [0, 1, 0, -1];

// WAVEFRONT BFS: Process wavefront until no more expansions possible
bool hasWavefront = true;

while (hasWavefront)
{
hasWavefront = false; // Will be set to true if we find any wavefront cells

// Use bounded scan instead of full matrix scan
int nextMinRow = mapHeight;
int nextMaxRow = -1;
int nextMinCol = mapWidth;
int nextMaxCol = -1;

// BOUNDED MATRIX SCAN: Only scan the active region
for (int i = minRow; i = 0 && nc < mapWidth)
{
// QUEUE FREE NEIGHBORS: Add unvisited free cells to wavefront
if (bfsWorkspace[index, nr, nc] == 0) // If free and unvisited
{
bfsWorkspace[index, nr, nc] = 1; // Add to current wavefront
hasWavefront = true; // Continue processing

// Update scan bounds for next iteration
nextMinRow = Math.Min(nextMinRow, nr);
nextMaxRow = Math.Max(nextMaxRow, nr);
nextMinCol = Math.Min(nextMinCol, nc);
nextMaxCol = Math.Max(nextMaxCol, nc);
}
}
}
}
}
}

// Update bounds for next iteration (only if we have new wavefront)
if (hasWavefront)
{
minRow = nextMinRow;
maxRow = nextMaxRow;
minCol = nextMinCol;
maxCol = nextMaxCol;
}
}

// EQUIVALENCE CHECK: Compare with first position in this group Only positions after the
// first (positionIndex > 0) need checking The first position is always kept as the representative
if (positionIndex > 0)
{
// FIRST POSITION: Get the representative position for this group
int firstPositionIndex = groupIndex * maxPositionsPerGroup; // First position in this group
ushort firstManPos = manPositions[firstPositionIndex];
byte firstManRow = (byte)(firstManPos >> 8);
byte firstManCol = (byte)(firstManPos & 0xFF);

// BOUNDS CHECK: Ensure first position is valid
if (firstManRow < mapHeight && firstManCol < mapWidth)
{
// REACHABILITY TEST: Check if positions can reach each other Two positions are
// equivalent if:
// 1. Current position can reach first position
// (bfsWorkspace[firstPositionIndex, manRow, manCol] == 2)
// 2. OR first position can reach current position (bfsWorkspace[index,
// firstManRow, firstManCol] == 2)
bool currentReachesFirst = bfsWorkspace[firstPositionIndex, manRow, manCol] == 2;
bool firstReachesCurrent = bfsWorkspace[index, firstManRow, firstManCol] == 2;

if (currentReachesFirst || firstReachesCurrent)
{
resultArray[index] = 1; // Mark as equivalent (skip this position)
}
// If not equivalent, resultArray[index] remains 0 (keep this position)
}
}
// For positionIndex == 0, resultArray[index] remains 0 (always keep first position)
}
< /code>
и второй (который даже не собирался в начале, но теперь он доходит до конца успешной компиляции после того, как все списки LINQ и LINQ были удалены, и все вызовы подметодов были вставлены): < /p>
///
/// This kernel passes to the GPU the following work:
/// 1) for each combination in the chunk, it creates the 4n cases of possible sons
/// 2) checks that each son is geometrically compatible ( no collisions on diamonds nor walls)
/// 3) checks that the man can do the movement geometrically
/// 4) if all passes, then it performs a reachability test from the man in the original
/// combination position
/// 5) if also this passes, then son is admissible therefore this combination cannot be
/// a deadlock, and it erases it in the chunk array
///
public static void FirstPassFullKernel(
Index1D index1d,
int currentOrder,
ArrayView1D chunk, // the chunk
ArrayView2D layout, // the map layout without diamonds
ArrayView3D bsf)// some room for man reachability tests
{
//In this method the directions are: 1:UP, 2:RIGHT, 3:DOWN, 0: LEFT (iterations starts from 1)
int index = index1d;
if (chunk[index] == 0) return;
// if order == 3 -> man positions are indices 0, 4, 8, 12, ...
int combLen = currentOrder + 1;
//process only cases where the index is on the man
if (index % combLen != 0) return;
// the combination number
int combIndex = index / combLen;

int totIterationsPerCombination = currentOrder * 4;
for (int dia = 1; dia 1 && bsf[bsfIndex, r - 1, c] == 0)
{
bsf[bsfIndex, r - 1, c] = 1;
compare = (ushort)((r - 1) * 256 + c);
if (compare == requiredManPosition) { manCanReach = true; break; }
if (nextTurnMinRow > r - 1) nextTurnMinRow = r - 1;
}
// RIGHT
if (c < maxCols - 1 && bsf[bsfIndex, r, c + 1] == 0)
{
bsf[bsfIndex, r, c + 1] = 1;
compare = (ushort)(r * 256 + c + 1);
if (compare == requiredManPosition) { manCanReach = true; break; }
if (nextTurnMaxCol < c + 1) nextTurnMaxCol = c + 1;
}
// DOWN
if (r < maxRows - 1 && bsf[bsfIndex, r + 1, c] == 0)
{
bsf[bsfIndex, r + 1, c] = 1;
compare = (ushort)((r + 1) * 256 + c);
if (compare == requiredManPosition) { manCanReach = true; break; }
if (nextTurnMaxRow < r + 1) nextTurnMaxRow = r + 1;
}
// LEFT
if (c > 1 && bsf[bsfIndex, r, c - 1] == 0)
{
bsf[bsfIndex, r, c - 1] = 1;
compare = (ushort)(r * 256 + (c - 1));
if (compare == requiredManPosition) { manCanReach = true; break; }
if (nextTurnMinCol > c - 1) nextTurnMinCol = c - 1;
}
}
}
if (manCanReach) break;
}
if (manCanReach) break;
}
}

if (manCanReach)
{
//this is an eligible son therefore the state cannot be deadlock
//cancel the partial state from the chunk by erasing the man position
chunk[index] = 0;
}
}
}
}
}
}
}
< /code>
Ядра длинные и запутанные, но первые компилируют правильно и загружаются с помощью вызова, подобного: < /p>
var kernel = accelerator.LoadAutoGroupedStreamKernel<
Index1D,
ArrayView1D,
ArrayView1D,
ArrayView1D,
ArrayView2D,
int,
int,
int,
ArrayView3D,
ArrayView1D>
(PurgeEquivalentManPositionsKernel);
< /code>
Второй не удастся в том же объявлении; < /p>
var kernel = accelerator.LoadAutoGroupedStreamKernel<
Index1D,
int, //current order
ArrayView1D, // the chunk
ArrayView2D, // the map layout without diamonds
ArrayView3D// some room for man reachability tests
>(FirstPassFullKernel);
< /code>
дает badimageformatexception (System.sr.MetAdataHeaderTOOSMALL); < /code> -> «Заголовок метаданных слишком маленький». Неужели могло бы попытаться клонировать моду первого, которую я уверен, работает правильно, удалив все нерадостные переменные, локальные ассигнования не известны во время компиляции, списков, LINQ и всего еще.
Где может быть ошибка? Ilgpu не предоставляет больше информации, чем то, что я здесь показываю, и я еще не осознаю путь кода, который делает реальную компиляцию (который должен быть тем, который не удается, намного более высока, чем джиттер).


Подробнее здесь: https://stackoverflow.com/questions/797 ... -compiling
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»