LINUX.ORG.RU

Метод прогонки для разделяемой памяти. Видимо совсем запуталась в индексах.

 ,


1

2

Решаю трехдиагональные матрицы методом прогонки. z- число систем,n- число уравнений в системе.Не правильно считает элементы массива.Первый раз работаю с разделяемой памятью и не могу сообразить как правильно проставлять индексы. Сам код работает, а при выводе элемента массива на экран выдает невозможные значения.Помогите,пожалуйста, найти ошибку.

const int l = 128;
__global__ void func(int n, float *a, float *b, float *c, float *f, float *x)
{

	__shared__ float bufa[l];// разделяемая память
	__shared__ float bufb[l];
	__shared__ float bufc[l];
	__shared__ float buff[l];
	__shared__ float bufx[l];
	__shared__ float alpha[l];
	__shared__ float betta[l];
	int j = threadIdx.x;
	int r = j*n;
	float m;
	for (int i = 1; i<n*l; i++)
	{
		bufa[i] = a[blockIdx.x*n + i];// запись значений из глобальной памяти в разделяемую
	}
	for (int i = 0; i<n*l - 2; i++)
	{
		bufb[i] = b[blockIdx.x*n + i];
	}
	for (int i = 0; i<n*l - 1; i++)
	{
		bufc[i] = c[blockIdx.x*n + i];
	}
	for (int i = 0; i < n*l; i++)
	{
		buff[i] = f[blockIdx.x*n + i];
	}
	for (int i = 0; i<n*l; i++)
	{
		bufx[i] = x[blockIdx.x*n+ i];

	}

	__syncthreads();

	for (int i = 1 ; i < n ; i++)
	{
	m = bufa[i+r] / bufc[i - 1+r];
	bufc[i+r] = bufc[i+r] - m*bufb[i - 1+r];
	buff[i+r] = buff[i+r] - m*buff[i - 1+r];
	}
	__syncthreads();
	bufx[n - 1 + r] = buff[n - 1 + r] / bufc[n - 1 + r];
	for (int i = n - 1 ; i >= 0; i--){
		bufx[i] = (buff[i+r] - bufb[i+r] * bufx[i + 1+r]) / bufc[i+r];
		
	}
}



Последнее исправление: UTKA (всего исправлений: 2)

Думаешь, кто-то будет вникать в эту простыню? Ты хоть скажи, что там происходит. Решаешь СЛАУ с трехдиагональной матрицей?

buddhist ★★★★★
()
Ответ на: комментарий от buddhist

Да. Тут z систем, в каждой из которых n уравнений. Решается трехдиагональная матрица методом прогонки. Вот есть код на с и мне нужно написать то же самое cuda с разделяемой памятью.Никак не могу определиться с правильными индексами

 сод на с
/**
	 * n - число уравнений (строк матрицы)
	 * b - диагональ, лежащая над главной (нумеруется: [0;n-2])
	 * c - главная диагональ матрицы A (нумеруется: [0;n-1])
	 * a - диагональ, лежащая под главной (нумеруется: [1;n-1])
	 * f - правая часть (столбец)
	 * x - решение, массив x будет содержать ответ
	 */
void solveMatrix (int n, double *a, double *c, double *b, double *f, double *x)
{
	double m;
	for (int i = 1; i < n; i++)
	{
		m = a[i]/c[i-1];
		c[i] = c[i] - m*b[i-1];
		f[i] = f[i] - m*f[i-1];
	}

	x[n-1] = f[n-1]/c[n-1];

	for (int i = n - 2; i >= 0; i--)
		x[i]=(f[i]-b[i]*x[i+1])/c[i];

}
UTKA
() автор топика

И как в точности тебе должны помочь? Придет какой-то гуру, окинет строгим взглядом этот код и тыкнет в ошибку? Или кто-то должен за тебя это отлаживать?

Попробуй взять z = 1. Убедись, что работает. Если работает, то бери z = 2 и ищи, где не работает.

hotpil ★★★★
()
Ответ на: комментарий от UTKA

Странная индексация массивов. В поддиагонали нулевой элемент никогда не используется.

hotpil ★★★★
()
Ответ на: комментарий от hotpil

Я просто не понимаю принцип индексации в разделяемой памяти. Я прекрасно понимаю,что там отличается от глобальной,но как это отразить в этом случае не имею представления. У меня программа выдает время выполнения алгоритма,а сами значения не считает не при каких z и n. Я предполагаю,что у меня ошибка именно в циклах с формулами,потому что как раз там я не понимаю как правильно взять индекс.

UTKA
() автор топика
Ответ на: комментарий от UTKA

Тогда я не понимаю, что ты хочешь сделать. Нужно, чтобы несколько систем решались параллельно, так? Тогда для одной системы все должно работать, потому что никакого разделения памяти не будет.

hotpil ★★★★
()
Ответ на: комментарий от hotpil

Да,видимо у меня проблемы и без параллельных решений, потому что для глобальной памяти это тоже не работает. Спасибо,буду искать ошибку.

UTKA
() автор топика
Ответ на: комментарий от buddhist

Да, код на с работает правильно, у меня так же есть рабочий правильно код для глобальной памяти

UTKA
() автор топика
Ответ на: комментарий от anonymous

в смысле? Мне их нужно поместить в цикл?

UTKA
() автор топика
Ответ на: комментарий от I-Love-Microsoft

Я не знаю. Есть в принципе какой-то CUDA-gdb, видимо можно прямо на карте отлаживать.

hotpil ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.