如何解决GPU.js 代码获取数组的最大值
我正在尝试使用 GPU.js 使用简单的 Jacobi 迭代运行拉普拉斯求解器计算。
我想要实现的一件事是在每次迭代后计算数组的“最大误差”。也许一个更简单的问题是在迭代后计算整个数组的最大值,希望使用 GPU。我想以此作为收敛标准来停止计算。
我不知道如何做到这一点,也不清楚如何从示例中获取“并行化”函数中的单个值。
感谢任何帮助。
这是我正在使用的代码
<html>
<head>
<title>Laplace Solver Speed Test Using GPU.js library
</title>
</head>
<body>
<p><button onclick="btn_runcalculation_click(event)">Start calculation</button> </p>
<br>Laplace Solver Speed Test Using GPU.js library
<br> <a href = "https://gpu.rocks/#/" >https://gpu.rocks/#/</a>
<br><br>In Opera browser
<br> 500 x 500 with 2 electrodes at position 20 and 480. Height of 200 each.
Left electrode at +1 V and right electrode at -1V.
447 iterations
<br>
<br>Iteration = <span id="txt_iter"></span>
<br>
<br>Number of iterations = <span id="txt_niter"></span>
<br>Max change = <span id="txt_maxchange"></span>
<br> Time taken to complete / ms = <span id="txt_tiMetaken"></span>
<br>
<br>For some reason it only runs in server,not in client mode
<script src="gpu-browser.min.js"></script>
<script>
//Initialisation,no need for init() function
const arraydim=500;
//Setup potential array
let pot2DArray = [];
let electrodes2DArray = [];
let pot2DArray_buffer = [];
//const iterationVMaxError = 1e-3;
//let maxchange=0;
let niterations = 0;
const maxiterations = 447;
const gpu = new GPU();
function init(){
niterations=0;
pot2DArray = new Array(arraydim); //Creates a new array
pot2DArray_buffer = new Array(arraydim);
electrodes2DArray = new Array(arraydim);
for (let iy = 0 ; iy<arraydim ; iy++){
pot2DArray[iy] = new Array(arraydim);
pot2DArray_buffer[iy] = new Array(arraydim);
electrodes2DArray[iy] = new Array(arraydim);
for (let ix = 0 ; ix < arraydim ; ix++){
pot2DArray[iy][ix] = 0;
pot2DArray_buffer[iy][ix] = 0;
electrodes2DArray[iy][ix] = 0.0;
if ( ix==20 && (iy>=150 && iy<350) ) {
pot2DArray[iy][ix] = 1;
electrodes2DArray[iy][ix] = 1.0;
}
if ( ix==480 && (iy>=150 && iy<350) ) {
pot2DArray[iy][ix] = -1;
electrodes2DArray[iy][ix] = 1.0;
}
}
}
}
function btn_runcalculation_click(event){
event.preventDefault();
init();
let t0= (new Date()).getTime();
doCalculationGPU();
let t1= (new Date()).getTime();
let deltat = t1-t0;
//Completed,Now display results
document.getElementById("txt_niter").innerHTML= niterations.toString();
document.getElementById("txt_tiMetaken").innerHTML= deltat.toString();
}
var txt_iter = document.getElementById("txt_iter");
function doCalculationGPU(){
//Todo
//Setting up convergence is pretty hard. GPU is good to operate in each pixel in the array individually
//Instead,this will run several iterations (maxiterations)
niterations=0;
do {
pot2DArray_buffer = doSingleIterationGPU( pot2DArray,electrodes2DArray,arraydim );
niterations++;
pot2DArray = pot2DArray_buffer;
txt_iter.innerHTML = niterations.toString();
}while (niterations< maxiterations) ;
}
const doSingleIterationGPU = gpu.createKernel( function (pot2DArray,arraydim) {
//Do the calculation for each output pixel with coordinates (ix,iy)
//The result at each pixel is the "Average" of all the values in points around it
// (Laplace - Jacob algorithm)
let sum=0.0;
let nsums = 0.0;
//let vchange=0;
let iy= this.thread.y;
let ix= this.thread.x;
let newval= pot2DArray[iy][ix];
if ( electrodes2DArray[iy][ix] == 0.0){
if (iy>0){
sum +=pot2DArray[iy-1][ix];
nsums++;
}
if (iy<arraydim-1){
sum += pot2DArray[iy+1][ix];
nsums++;
}
if (ix>0){
sum += pot2DArray[iy][ix-1];
nsums++;
}
if (ix<arraydim-1){
sum += pot2DArray[iy][ix+1];
nsums++;
}
//sets the new value
if (nsums>0) {
newval = sum/nsums;
}
}
return newval;
}
).setoutput([arraydim,arraydim]); //Results in a 2D array with the new values that are returned
</script>
</body>
</html>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。