簡體   English   中英

可以使用 BigDecimal 或 float64array 的 gpu.js 嗎?

[英]gpu.js with BigDecimal or float64array possible?

我正在gpu.js的幫助下編寫一個 mandelbrot 計算器,直到現在,一切正常。 我面臨的唯一問題是,GPU 只想計算 32 位浮點數。 或者至少這是官方文檔告訴我的。
但是,當使用同樣在同一 GPU 上運行的pythonnumba進行相同的計算時,在渲染 mandelbrot 分形時會更加精確。
使用 Python,我幾乎可以得到1e-15左右,而在 Javascript 中,圖像在1e-7左右變得模糊。

Python內核:

@cuda.jit(device=True)
def mandel(x, y, max_iters):
    c = complex(x, y)
    z = 0.0j
    for i in range(max_iters):
        z = z * z + c
        if (z.real * z.real + z.imag * z.imag) >= 4:
            return i

    return max_iters

Javascript內核:

const recalculateMandelbrot = gpu.createKernel(function(x_start, x_end, y_start, y_end, iters){
    let c_re = x_start + (x_end - x_start) * this.thread.x / 1024;
    let c_im = y_start + (y_end - y_start) * this.thread.y / 1024;
    let z_re = 0, z_im = 0;
    let z_re_prev = 0;

    for(let i = 0; i < iters; i++) {
        z_re_prev = z_re;
        z_re = z_re * z_re - z_im * z_im + c_re;
        z_im = z_re_prev * z_im + z_re_prev * z_im + c_im;

        if ((z_re * z_re + z_im * z_im) >= 4) {
            return i;
        }
    }
    return iters;
}).setOutput([1024, 1024]).setPrecision('single');

算法是等價的,只是在 Python 中,我可以使用它內置的complex類型。

所以我考慮使用 BigDecimal,在那里我可以實現任意精度(所以我可以放大到我想要的任何地方),但我不知道如何將它添加到我的 gpu 內核中。

更新:

python 工作更精確的原因是complex類型由兩個 64 位浮點數組成。 所以 JavaScript 計算不那么精確的原因是 JavaScript 本身。
所以我現在的問題集中在如何big.js添加到我的 gpu 內核上?

這里有自定義內核測試文件: https ://github.com/gpujs/gpu.js/blob/1be50c09ed4edb7c7e846b1815414ef504089ab6/test/features/add-custom-native-function.js

使用此內核示例:

const glslDivide = `float divide(float a, float b) {
  return a / b;
}`;

也許有一種方法可以使用“double”代替“float”,並使用它代替簡單的乘法和加法。

我不知道如何使用 glsl 但如果后端可以以某種方式附加到 glsl ,這應該可以。 “double”也需要 glsl 4.0,所以它可能不起作用。

即使它有效,它仍然需要所有迭代遞歸,因為雙精度沒有“狀態變量”定義。 就像調用相同的函數直到達到最大迭代一樣。 應該有兩個函數參數來跟蹤虛部和實部,以及另外兩個函數參數來跟蹤迭代次數和可能的 c 值。 考慮到遞歸的深度是有限的,它可能再次不起作用。


即使在 webgl 后端, https://github.com/gpujs/gpu.js/blob/1be50c09ed4edb7c7e846b1815414ef504089ab6/src/backend/web-gl/fragment-shader.js看起來你可以編輯一些函數的字符串(比如模塊在那里)並像乘法/加法一樣使用它。

您還可以在此處閱讀以獲取由四個 32 位值模擬的兩個 64 位值相乘/相加的靈感: https ://github.com/visgl/luma.gl/blob/master/modules/shadertools/src/modules/fp64/fp64 -算術.glsl.ts

無論如何,緩沖區(在 Js 環境和 GPU 驅動程序之間)可能根本不起作用,並且您在內核中被 100% 的函數式編程困住了(沒有對 64 位變量的狀態處理)。

這些都不是好的選擇。 您應該使用一個庫,讓您將本機內核編寫為字符串(如https://github.com/kashif/node-cuda/blob/master/test/test.js )並直接從 Javascript 使用它,以便您幾乎可以做任何你會在 CUDA/OpenCL 中做的事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM