Nano Hash - криптовалюты, майнинг, программирование

Реализация алгоритма F#/Accelerator v2 DFT, вероятно, неверна

Я пытаюсь поэкспериментировать с концепциями программно-определяемого радио. Из этого статья Я попытался реализовать дискретное преобразование Фурье с параллелизмом на GPU.

Я почти уверен, что мог бы предварительно вычислить 90 градусов sin(i) cos(i), а затем просто перевернуть и повторить, а не то, что я делаю в этом коде, и что это ускорит его. Но пока я даже не думаю, что получаю правильные ответы. Ввод со всеми нулями дает 0-й результат, как я и ожидал, но все 0,5 в качестве входных данных дают 78,9985886f (в этом случае я тоже ожидаю 0-го результата). В общем, я просто в замешательстве. У меня нет хороших входных данных, и я не знаю, что делать с результатом или как его проверить.

Этот вопрос связан с другим моим сообщением здесь

open Microsoft.ParallelArrays
open System

 // X64MulticoreTarget is faster on my machine, unexpectedly
let target = new DX9Target() // new X64MulticoreTarget()

ignore(target.ToArray1D(new FloatParallelArray([| 0.0f |]))) // Dummy operation to warm up the GPU

let stopwatch = new System.Diagnostics.Stopwatch() // For benchmarking

let Hz = 50.0f
let fStep = (2.0f * float32(Math.PI)) / Hz
let shift = 0.0f // offset, once we have to adjust for the last batch of samples of a stream

// If I knew that the periodic function is periodic 
// at whole-number intervals, I think I could keep 
// shift within a smaller range to support streams 
// without overflowing shift - but I haven't 
// figured that out

//let elements = 8192 // maximum for a 1D array - makes sense as 2^13
//let elements = 7240 // maximum on my machine for a 2D array, but why?
let elements = 7240

// need good data!!
let buffer : float32[,] = Array2D.init<float32> elements elements (fun i j -> 0.5f) //(float32(i * elements) + float32(j))) 

let input = new FloatParallelArray(buffer)
let seqN : float32[,] = Array2D.init<float32> elements elements (fun i j -> (float32(i * elements) + float32(j)))
let steps = new FloatParallelArray(seqN)
let shiftedSteps = ParallelArrays.Add(shift, steps)
let increments = ParallelArrays.Multiply(fStep, steps)
let cos_i = ParallelArrays.Cos(increments) // Real component series
let sin_i = ParallelArrays.Sin(increments) // Imaginary component series

stopwatch.Start()
// From the documentation, I think ParallelArrays.Multiply does standard element by 
// element multiplication, not matrix multiplication
// Then we sum each element for each complex component (I don't understand the relationship 
// of this, or the importance of the generalization to complex numbers)
let real = target.ToArray1D(ParallelArrays.Sum(ParallelArrays.Multiply(input, cos_i))).[0]
let imag = target.ToArray1D(ParallelArrays.Sum(ParallelArrays.Multiply(input, sin_i))).[0]
printf "%A in " ((real * real) + (imag * imag)) // sum the squares for the presence of the frequency
stopwatch.Stop()

printfn "%A" stopwatch.ElapsedMilliseconds

игнорировать (System.Console.ReadKey())

27.06.2010

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

Ответы:


1

Разделяю ваше удивление, что ваш ответ не ближе к нулю. Я бы предложил написать наивный код для выполнения вашего ДПФ на F # и посмотреть, сможете ли вы отследить источник несоответствия.

Вот что, я думаю, вы пытаетесь сделать:

let N = 7240
let F = 1.0f/50.0f
let pi = single System.Math.PI

let signal = [| for i in 1 .. N*N -> 0.5f |]

let real = 
  seq { for i in 0 .. N*N-1 -> signal.[i] * (cos (2.0f * pi * F * (single i))) }
  |> Seq.sum

let img = 
  seq { for i in 0 .. N*N-1 -> signal.[i] * (sin (2.0f * pi * F * (single i))) }
  |> Seq.sum

let power = real*real + img*img

Надеюсь, вы сможете использовать этот наивный код, чтобы лучше понять, как должен вести себя код ускорителя, что поможет вам при тестировании кода ускорителя. Имейте в виду, что отчасти причиной расхождения может быть просто точность вычислений — в ваших массивах ~ 52 миллиона элементов, поэтому накопление общей ошибки 79 может на самом деле не так уж плохо. FWIW, я получаю мощность ~ 0,05 при запуске вышеуказанного кода одинарной точности, но мощность ~ 4e-18 при использовании эквивалентного кода с числами двойной точности.

27.06.2010

2

Два предложения:

  • убедитесь, что вы не путаете градусы с радианами
  • попробуйте сделать это без параллелизма или просто с асинхронными функциями F# для параллелизма

(В F#, если у вас есть массив с плавающей запятой

let a : float[] = ...

затем вы можете «добавить шаг ко всем из них параллельно», чтобы создать новый массив с

let aShift = a |> (fun x -> async { return x + shift }) 
               |> Async.Parallel |> Async.RunSynchronously

(хотя я ожидаю, что это может быть медленнее, чем просто выполнение синхронного цикла).)

27.06.2010
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..