Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ check:
-fsyntax-only -Iinclude test/ptoas_linx_type_compat.cpp
$(CXX) -std=c++20 -D__linx -include test/linx_host_type_shim.hpp \
-fsyntax-only -Iinclude test/pto0583_contract.cpp
$(CXX) -std=c++20 -D__linx -fsyntax-only -Iinclude \
test/linx_group_runtime_api.cpp
$(CC) -std=c11 -D__linx -fsyntax-only -Iinclude \
test/linx_group_runtime_api.c
bash -n test/tileop_api/compile.all test/tileop_api/run_negatives.sh \
test/tileop_api/verify_pto0583_asm.sh \
test/tileop_api/verify_target_cxx_frontend.sh
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ canonical aliases.
- [Comparison operations](docs/tileop-usage/cmp.md)
- [Sorting operations](docs/tileop-usage/sort.md)
- [Fixed-point matrix wrappers](docs/tileop-usage/tmatmul-fixp.md)
- [Hosted four-PE group runtime](docs/tileop-usage/group-runtime.md)

## Validation

Expand Down
41 changes: 41 additions & 0 deletions docs/tileop-usage/group-runtime.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Hosted four-PE group runtime

The first hosted SMT4 ABI keeps the process runtime on PE0 and uses a small
worker entry for PE1 through PE3. It is intentionally static-only,
single-shot, and independent of glibc or musl internals.

## Required symbols

Applications define one worker body:

```cpp
extern "C" int __linx_group_worker_main(uint32_t peId, void *context);
```

PE0 calls:

```cpp
int status = linx_group_run(context);
```

The linked compiler runtime provides `linx_group_run()` and the non-returning
`__linx_group_worker_start` entry consumed by gfrun.

## Ownership

- PE0 owns libc startup, TLS, file descriptors, input/output, and process
exit.
- PE1 through PE3 use independent stacks and do not call libc or issue
syscalls.
- `THREAD_ID` selects PE0 through PE3; `BLOCKID` remains the core work ID.
- The worker body publishes one completion status per PE and then parks until
PE0 terminates the process.

## ELF boundary

The first ABI supports static executable and static PIE carriers. A
`PT_INTERP` image is rejected. A static PIE may contain `PT_DYNAMIC` for
self-relocation without becoming a dynamically interpreted carrier.

The executable must retain `__linx_group_worker_start` in its symbol table so
the functional model can assign PE1 through PE3 their initial PC.
28 changes: 28 additions & 0 deletions include/common/linx_group_runtime.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#ifndef LINX_GROUP_RUNTIME_H
#define LINX_GROUP_RUNTIME_H

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

/* One static ELF provides one group worker body. A direct symbol avoids a
* function-pointer relocation in the first gfrun ABI. */
int __linx_group_worker_main(uint32_t pe_id, void *context);

/* Run the ELF's worker body on the fixed four-PE group. PE0 calls this after
* hosted libc and input initialization; PE1..PE3 are already parked in the
* entry exported below. The first non-zero PE status is returned. */
int linx_group_run(void *context);

/* Static hosted ELF ABI symbol consumed by gfrun. This entry never enters
* libc and never returns. */
__attribute__((noreturn, used, visibility("default"))) void
__linx_group_worker_start(void);

#ifdef __cplusplus
}
#endif

#endif
1 change: 1 addition & 0 deletions include/common/pto_tileop.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "common/pto_tile.hpp"
#include "common/tileop_api.hpp"
#include "common/global_iterator.hpp"
#include "common/linx_group_runtime.h"
#include "common/tile_tensor_impl.hpp"
#include "common/debug_utils.hpp"

Expand Down
7 changes: 7 additions & 0 deletions test/linx_group_runtime_api.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include <common/linx_group_runtime.h>

int __linx_group_worker_main(uint32_t pe_id, void *context) {
return context == 0 ? (int)pe_id : 0;
}

int call_group_runtime_c(void *context) { return linx_group_run(context); }
7 changes: 7 additions & 0 deletions test/linx_group_runtime_api.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include <common/linx_group_runtime.h>

extern "C" int __linx_group_worker_main(uint32_t peId, void *context) {
return context == nullptr ? static_cast<int>(peId) : 0;
}

int call_group_runtime(void *context) { return linx_group_run(context); }