Skip to content

Commit

Permalink
feat: launching setup kernels from main
Browse files Browse the repository at this point in the history
  • Loading branch information
sethp committed May 14, 2024
1 parent a278076 commit 02ba5bd
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 73 deletions.
42 changes: 42 additions & 0 deletions NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -496,3 +496,45 @@ git submodule foreach git push
git ci -av
git push
```
### Implementing the actual dispatch
First target: just statically invoke the FILL kernel 16x1x1 on the same device.
PipelineExecutor thinks of itself as running a single task at a time, so duplicating that and accessing private fields (OOPs, amirite?) successfully gets us to:
```
Aborted(Assertion failed: Id.X < GroupSize.X * NumGroups.X && Id.Y < GroupSize.Y * NumGroups.Y && Id.Z < GroupSize.Z * NumGroups.Z, at: ../wasm/talvos/lib/talvos/PipelineExecutor.cpp,2313,doSwtch)
```
Is this "device is full" message? Let's try a smaller invocation; nope, still doesn't like it.
Ah, it's because PipelineExecutor is chock full o' static & thread_local data, right. So we push a
hmm, C++
```c++
talvos::PipelineStage *Stage = new talvos::PipelineStage(
Dev, CurrentModule,
CurrentModule->getEntryPoint("FILL", 5 /*EXEC_MODEL_GLCOMPUTE*/), {});
talvos::ComputePipeline ComputePipeline(Stage);
```

vs.

```c++
talvos::PipelineStage Stage = new talvos::PipelineStage(
Dev, CurrentModule,
CurrentModule->getEntryPoint("FILL", 5 /*EXEC_MODEL_GLCOMPUTE*/), {});

talvos::ComputePipeline ComputePipeline(&Stage);
```
with
```c++
ComputePipeline::~ComputePipeline() { delete Stage; }
```

(in fairness, the comment _did_ say that ownership will be transferred)
2 changes: 1 addition & 1 deletion wasm/talvos
Binary file modified wasm/talvos-wasm.wasm
Binary file not shown.
Binary file modified wasm/talvos-wasm.wasm.dwp
Binary file not shown.
96 changes: 34 additions & 62 deletions wasm/talvos.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import talvos from './talvos-wasm';
import main from './testdata/main.spvasm?raw'
// TODO: replace with main.spvasm ?
import fill from '../content/talvos/fill.spvasm.?raw'
import dup from './testdata/dup_entry.spvasm?raw'


describe('talvos', () => {
test('inits', async () => {
Expand All @@ -29,36 +31,6 @@ describe('talvos', () => {
// TODO: this is sensitive to the line number of the assert
expect(stderr).toMatchSnapshot();
})
test('oob_write', async () => {
let [stdout, stderr] = ['', ''];
let instance = await talvos({
print: (text: any) => { stdout += text + "\n"; },
printErr: (text: any) => { stderr += text + "\n"; },
});


instance.cwrap('test_entry', 'void', ['string', 'string', 'string'])(
fill,
'FILL',
`
BUFFER a 64 UNINIT
DESCRIPTOR_SET 0 0 0 a
DISPATCH 17 1 1
`
)

expect(stdout).to.be.empty;
expect(stderr).toMatchInlineSnapshot(`
"
Invalid store of 4 bytes to address 0x1000000000040 (Device scope)
Entry point: %1 FILL
Invocation: Global(16,0,0) Local(0,0,0) Group(16,0,0)
OpStore %18 %14
"
`);
})
test('main kernel', async () => {
let [stdout, stderr] = ['', ''];
let instance = await talvos({
Expand Down Expand Up @@ -88,40 +60,40 @@ DISPATCH 17 1 1
expect(stdout).toMatchInlineSnapshot(`
"
Buffer 'fill' (64 bytes):
fill[0] = 431188
fill[1] = 431188
fill[2] = 8
fill[3] = 8
fill[4] = 24
fill[5] = 26
fill[6] = 508392
fill[7] = 10
fill[8] = 10
fill[9] = 0
fill[10] = 48
fill[11] = 26
fill[12] = 512576
fill[13] = 8
fill[14] = 8
fill[15] = 0
fill[0] = 1
fill[1] = 1
fill[2] = 1
fill[3] = 1
fill[4] = 1
fill[5] = 1
fill[6] = 1
fill[7] = 1
fill[8] = 1
fill[9] = 1
fill[10] = 1
fill[11] = 1
fill[12] = 1
fill[13] = 1
fill[14] = 1
fill[15] = 1
Buffer 'series' (64 bytes):
series[0] = 431124
series[1] = 73
series[2] = 512944
series[3] = 431164
series[4] = 33
series[5] = 1
series[6] = 144
series[7] = 49
series[8] = 512544
series[9] = 508608
series[10] = 6
series[11] = 6
series[12] = 24
series[13] = 26
series[14] = 0
series[15] = 6
series[0] = 0
series[1] = 1
series[2] = 2
series[3] = 3
series[4] = 4
series[5] = 5
series[6] = 6
series[7] = 7
series[8] = 8
series[9] = 9
series[10] = 10
series[11] = 11
series[12] = 12
series[13] = 13
series[14] = 14
series[15] = 15
"
`);
})
Expand Down
58 changes: 58 additions & 0 deletions wasm/talvos[fixme].test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { describe, expect, test } from 'vitest';
import talvos from './talvos-wasm';
// TODO: replace ?
import fill from '../content/talvos/fill.spvasm.?raw'
import dup from './testdata/dup_entry.spvasm?raw'

// fixme: these tests are descriptive, not normative (they're bad feedback)
describe('talvos FIXMEs', () => {
test('oob_write', async () => {
let [stdout, stderr] = ['', ''];
let instance = await talvos({
print: (text: any) => { stdout += text + "\n"; },
printErr: (text: any) => { stderr += text + "\n"; /*console.error(text)*/ },
});


instance.cwrap('test_entry', 'void', ['string', 'string', 'string'])(
fill,
'FILL',
`
BUFFER a 64 UNINIT
DESCRIPTOR_SET 0 0 0 a
DISPATCH 17 1 1
`
)

expect(stdout).to.be.empty;
expect(stderr).toMatchInlineSnapshot(`
"
Invalid store of 4 bytes to address 0x1000000000040 (Device scope)
Entry point: %1 FILL
Invocation: Global(16,0,0) Local(0,0,0) Group(16,0,0)
OpStore %18 %14
"
`);
})
test('duplicate EntryPoint', async () => {
let [stdout, stderr] = ['', ''];
let instance = await talvos({
print: (text: any) => { stdout += text + "\n"; },
printErr: (text: any) => { stderr += text + "\n"; /*console.error(text)*/ },
});


instance.cwrap('test_entry', 'void', ['string', 'string', 'string'])(
dup,
'main',
`DISPATCH 1 1 1`,
)
expect(stdout).to.be.empty;
expect(stderr).toMatchInlineSnapshot(`
"line 1: ERROR: Bad EntryPoint!
"
`)
})
})
16 changes: 16 additions & 0 deletions wasm/testdata/dup_entry.spvasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
; SPIR-V
; Version: 1.3
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %main_fn "main"
OpEntryPoint GLCompute %main_fn "main2"

; types
%void_t = OpTypeVoid
%void_fn_t = OpTypeFunction %void_t

; main entry point
%main_fn = OpFunction %void_t None %void_fn_t
%0 = OpLabel
OpReturn
OpFunctionEnd
18 changes: 8 additions & 10 deletions wasm/testdata/main.spvasm
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
; SPIR-V
; Version: 1.3
OpCapability Shader ; TODO: Kernel?
; OpCapability DeviceEnqueue
OpCapability DispatchTALVOS
; OpExtension "talvos_rt" ; TODO it'd be really nice to have this fail somehow
OpExtension "SPV_TALVOS_dispatch"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %main_fn "main" %gl_GlobalInvocationID
OpEntryPoint GLCompute %fill_fn "FILL" %gl_GlobalInvocationID
OpEntryPoint GLCompute %sers_fn "SERIES" %gl_GlobalInvocationID

; metadata (& pseudo-linker)
OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
Expand All @@ -17,12 +17,12 @@ OpDecorate %buf1 DescriptorSet 0
OpDecorate %buf1 Binding 1

; types
%uint32_t = OpTypeInt 32 0
%void_t = OpTypeVoid
%gbl_id_t = OpTypeVector %uint32_t 3
%void_t = OpTypeVoid
%void_fn_t = OpTypeFunction %void_t
%uint32_t = OpTypeInt 32 0
%gbl_id_t = OpTypeVector %uint32_t 3

%_arr_uint32_t = OpTypeRuntimeArray %uint32_t
%void_fn_t = OpTypeFunction %void_t

%_ptr_StorageBuffer_uint32_t = OpTypePointer StorageBuffer %uint32_t
%_arr_StorageBuffer_uint32_t = OpTypePointer StorageBuffer %_arr_uint32_t
Expand All @@ -40,10 +40,8 @@ OpDecorate %buf1 Binding 1
; main entry point
%main_fn = OpFunction %void_t None %void_fn_t
%0 = OpLabel
;%1 = OpEnqueueKernel ...
OpDispatchTALVOS ; %fill_fn 16 1 1


OpDispatchTALVOS ; %fill_fn 16 1 1
OpDispatchTALVOS ; %sers_fn 16 1 1
OpReturn
OpFunctionEnd

Expand Down

0 comments on commit 02ba5bd

Please sign in to comment.