/**
* Warranty & Liability
* To the extent permitted by applicable law and unless explicitly
* otherwise agreed upon, XLOG Technologies AG makes no warranties
* regarding the provided information. XLOG Technologies AG assumes
* no liability that any problems might be solved with the information
* provided by XLOG Technologies AG.
*
* Rights & License
* All industrial property rights regarding the information - copyright
* and patent rights in particular - are the sole property of XLOG
* Technologies AG. If the company was not the originator of some
* excerpts, XLOG Technologies AG has at least obtained the right to
* reproduce, change and translate the information.
*
* Reproduction is restricted to the whole unaltered document. Reproduction
* of the information is only allowed for non-commercial uses. Selling,
* giving away or letting of the execution of the library is prohibited.
* The library can be distributed as part of your applications and libraries
* for execution provided this comment remains unchanged.
*
* Restrictions
* Only to be distributed with programs that add significant and primary
* functionality to the library. Not to be distributed with additional
* software intended to replace any components of the library.
*
* Trademarks
* Jekejeke is a registered trademark of XLOG Technologies AG.
*/
import {
set, deref, is_structure, make_check, MAX_ARITY, check_nil,
exec_build, exec_unify, get_ctx
} from "../../nova/core.mjs";
import {
int32
} from "../misc/hacklib.mjs";
import {
GROUP_SIZE, device, pipeline
} from "./boot.mjs";
/******************************************************************/
/* Cmd Constructors */
/******************************************************************/
/**
* test_gpu_data_new(A, B): internal only
* The predicate succeeds in B with a pi-WAM buffer for the list A.
*/
function test_gpu_data_new(args) {
let alpha = exec_build(args[0]);
let res = gpu_list_ints(alpha);
return exec_unify(args[1], res);
}
function gpu_list_ints(obj) {
let peek = obj;
let i = 0;
while (is_structure(peek) &&
"." === peek.functor &&
peek.args.length === 2 &&
i < MAX_ARITY) {
i++;
peek = deref(peek.args[1]);
}
check_nil(peek);
let buf = new ArrayBuffer(i * 4);
let args = new Int32Array(buf);
peek = obj;
i = 0;
while (is_structure(peek) &&
"." === peek.functor &&
peek.args.length === 2) {
let val = deref(peek.args[0]);
args[i++] = int32(val);
peek = deref(peek.args[1]);
}
return args;
}
/**
* test_gpu_comp_new(C, O, S, M): internal only
* The predicate succeeds in M with a new GPU backed π-WAM for
* the code buffer C, the offsets O and the state buffer S.
*/
function test_gpu_comp_new(args) {
let data = new Array(3);
for (let i = 0; i < 3; i++)
data[i] = exec_build(args[i]);
let entries = new Array(3);
for (let i = 0; i < 3; i++) {
let buf = device.createBuffer({
size: data[i].byteLength,
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
});
entries[i] = {
binding: i,
resource: {buffer: buf}
};
}
let bind = device.createBindGroup({
layout: pipeline.getBindGroupLayout(0),
entries: entries
});
for (let i = 0; i < 3; i++)
device.queue.writeBuffer(entries[i].resource.buffer, 0, data[i]);
return exec_unify(args[3], bind);
}
/**
* test_gpu_comp_work(M, W): internal only
* The predicate succeeds in W with the current
* group size of the GPU backed π-WAM M.
*/
function test_gpu_comp_work(args) {
let alpha = exec_build(args[0]);
let res = GROUP_SIZE;
return exec_unify(args[1], res);
}
/******************************************************************/
/* Cmd Interface */
/******************************************************************/
/**
* test_gpu_comp_submit(M, K): internal only
* The predicate succeeds. As a side effect it
* starts the GPU backed π-WAM M with K groups.
*/
function test_gpu_comp_submit(args) {
let alpha = exec_build(args[0]);
let beta = exec_build(args[1]);
const commandEncoder = device.createCommandEncoder();
const passEncoder = commandEncoder.beginComputePass();
passEncoder.setPipeline(pipeline);
passEncoder.setBindGroup(0, alpha);
passEncoder.dispatchWorkgroups(int32(beta));
passEncoder.end();
device.queue.submit([commandEncoder.finish()]);
return true;
}
/**
* test_gpu_comp_done(W, P): internal only
* The predicate succeeds in P with a new promise
* that waits for the GPU backed π-WAM W to finish.
*/
function test_gpu_comp_done(args) {
let alpha = exec_build(args[0]);
let buf = get_ctx();
return exec_unify(args[1], join_promise(buf, alpha));
}
async function join_promise(buf, alpha) {
await device.queue.onSubmittedWorkDone();
}
/******************************************************************/
/* Cmd Init */
/******************************************************************/
export function main() {
set("gpu_data_new", 2, make_check(test_gpu_data_new));
set("gpu_comp_new", 4, make_check(test_gpu_comp_new));
set("gpu_comp_work", 2, make_check(test_gpu_comp_work));
set("gpu_comp_submit", 2, make_check(test_gpu_comp_submit));
set("gpu_comp_done", 2, make_check(test_gpu_comp_done));
}