Что я хочу сделать, это подать в мою матрицу mxn и параллельно построить n квадратных диагональных матриц для каждого столбца матрицы, выполнить операцию на каждой квадратной диагональной матрице и затем рекомбинировать результат. Как мне это сделать?Лучший способ добиться диагональности вектора CUDA
До сих пор я начинал с матрицы m x n; результат предыдущего вычисления матрицы, где каждый элемент вычисляется с использованием функции y = f (g (x)).
Это дает мне матрицу с n элементами столбца [f1, f2 ... fn], где каждый fn представляет собой вектор-столбец высоты m.
Отсюда я хочу различать каждый столбец матрицы относительно g (x). Дифференцируя fn (x) w.r.t. g (x) приводит к квадратной матрице с элементами f '(x). При ограничении эта квадратная матрица сводится к якобиану с элементами каждой строки по диагонали квадратной матрицы и равна fn ', а все остальные элементы равны нулю.
Отсюда причина, по которой необходимо построить диагональ для каждой из векторных строк fn.
Для этого я беру целевой вектор, определенный как A (hA x 1), который был извлечен из большей матрицы A (m x n). Затем я подготовил нулевую матрицу, определенную как C (hA x hA), которая будет использоваться для хранения диагоналей.
Цель состоит в том, чтобы диагонализировать вектор А в квадратную матрицу с каждым элементом из А, сидящим на диагонали С, при этом все остальное равно нулю.
Возможно, существуют более эффективные способы достижения этой цели, используя некоторую заранее подготовленную процедуру, не создавая совершенно новое ядро, но, пожалуйста, имейте в виду, что для этих целей этот метод необходим.
Код ядра (который работает), чтобы выполнить это показано здесь:
_cudaDiagonalizeTest << <5, 1 >> >(d_A, matrix_size.uiWA, matrix_size.uiHA, d_C, matrix_size.uiWC, matrix_size.uiHC);
__global__ void _cudaDiagonalizeTest(float *A, int wA, int hA, float *C, int wC, int hC)
{
int ix, iy, idx;
ix = blockIdx.x * blockDim.x + threadIdx.x;
iy = blockIdx.y * blockDim.y + threadIdx.y;
idx = iy * wA + ix;
C[idx * (wC + 1)] = A[idx];
}
Я немного подозрительным, что это очень наивный подход к решению и было интересно, если кто-то может дать пример как я мог бы сделать то же самое, используя
а) снижение
б) тяги
для векторов большого размера строки, хотелось бы, чтобы иметь возможность используйте возможности многопоточности GPU, чтобы вырезать задачу на небольшие задания и объединить каждый результат в конце с помощью __syncthreads().
На рисунке ниже показан желаемый результат.
Я прочитал NVIDIA's article on reduction, но не смог достичь желаемых результатов.
Любая помощь или объяснение будет очень приветствоваться.
Спасибо.
Матрица А мишень с 4-мя колоннами. Я хочу взять каждый столбец и скопировать его элементы в матрицу B как диагональ, итерацию через каждый столбец.
Я не уверен, что следую именно тому, что вы ищете. Не могли бы вы включить образец ввода и желаемый результат? Я не вижу, как сокращение относится к этой проблеме. –
Вы действительно уверены, что вам нужно это сделать вообще? Если у вас есть чисто диагональная матрица, лучший способ ее сохранить и использовать, как у вас уже есть, - как диагональный массив. Вы будете использовать много памяти, много пропускной способности памяти и много флопов, просто загружая и сохраняя нули, как правило, без уважительной причины. – talonmies
Диагонализация строки с отраженным вектором является лишь небольшим шагом в более крупной операции. То, что я пытаюсь, состоит в том, чтобы диагонализировать каждую строку матрицы amxn параллельно, выполнять вычисления с этими n диагонализованными квадратными матрицами (есть n строк в матрице mxn и, следовательно, n диагонализованных квадратных матриц после диагонализации каждого из них), а затем суммировать результаты вычисления снова вместе. Все это должно быть сделано в ядре. Есть ли эффективный способ сделать это? – guerillacodester