Skip to main content

softgpu_functional/
kernels.rs

1//! Built-in SoftGPU Functional IR kernels (Rust builders + JSON twins).
2
3use crate::ir::{KernargField, Op, Program, TypeId, SFIR_SCHEMA};
4
5fn base(name: &str, provenance: &str, body: Vec<Op>, layout: Vec<KernargField>) -> Program {
6    base_group(name, provenance, body, layout, 0)
7}
8
9fn base_group(
10    name: &str,
11    provenance: &str,
12    body: Vec<Op>,
13    layout: Vec<KernargField>,
14    group_bytes: u32,
15) -> Program {
16    Program {
17        schema: SFIR_SCHEMA.into(),
18        fidelity: "functional".into(),
19        note: "not_gfx1201_isa_emulation".into(),
20        name: name.into(),
21        source_provenance: provenance.into(),
22        kernarg_layout: layout,
23        group_bytes,
24        body,
25    }
26}
27
28/// `b[i] = a[i] + 1` for i = global_id_x. Pointers in kernarg at 0 and 8.
29pub fn tiny_add() -> Program {
30    base(
31        "tiny_add",
32        "fixtures/functional/tiny_add.ref.c (hand-translated to softgpu-sfir-v1)",
33        vec![
34            Op::GlobalId {
35                dst: "i".into(),
36                dim: 0,
37            },
38            Op::Const {
39                dst: "four".into(),
40                ty: TypeId::U64,
41                value: 4,
42            },
43            Op::Mul {
44                dst: "off".into(),
45                lhs: "i".into(),
46                rhs: "four".into(),
47                ty: TypeId::U64,
48            },
49            Op::KernargLoad {
50                dst: "pa".into(),
51                offset: 0,
52                ty: TypeId::U64,
53            },
54            Op::Add {
55                dst: "addr_a".into(),
56                lhs: "pa".into(),
57                rhs: "off".into(),
58                ty: TypeId::U64,
59            },
60            Op::LoadGlobal {
61                dst: "va".into(),
62                addr: "addr_a".into(),
63                ty: TypeId::I32,
64            },
65            Op::Const {
66                dst: "one".into(),
67                ty: TypeId::I32,
68                value: 1,
69            },
70            Op::Add {
71                dst: "out".into(),
72                lhs: "va".into(),
73                rhs: "one".into(),
74                ty: TypeId::I32,
75            },
76            Op::KernargLoad {
77                dst: "pb".into(),
78                offset: 8,
79                ty: TypeId::U64,
80            },
81            Op::Add {
82                dst: "addr_b".into(),
83                lhs: "pb".into(),
84                rhs: "off".into(),
85                ty: TypeId::U64,
86            },
87            Op::StoreGlobal {
88                addr: "addr_b".into(),
89                src: "out".into(),
90                ty: TypeId::I32,
91            },
92            Op::Ret,
93        ],
94        vec![
95            KernargField {
96                name: "a".into(),
97                offset: 0,
98                size: 8,
99                kind: "global_ptr".into(),
100            },
101            KernargField {
102                name: "b".into(),
103                offset: 8,
104                size: 8,
105                kind: "global_ptr".into(),
106            },
107        ],
108    )
109}
110
111/// `b[i] = a[i]` copy.
112pub fn tiny_copy() -> Program {
113    base(
114        "tiny_copy",
115        "SoftGPU-authored softgpu-sfir-v1 (scalar copy)",
116        vec![
117            Op::GlobalId {
118                dst: "i".into(),
119                dim: 0,
120            },
121            Op::Const {
122                dst: "four".into(),
123                ty: TypeId::U64,
124                value: 4,
125            },
126            Op::Mul {
127                dst: "off".into(),
128                lhs: "i".into(),
129                rhs: "four".into(),
130                ty: TypeId::U64,
131            },
132            Op::KernargLoad {
133                dst: "pa".into(),
134                offset: 0,
135                ty: TypeId::U64,
136            },
137            Op::Add {
138                dst: "addr_a".into(),
139                lhs: "pa".into(),
140                rhs: "off".into(),
141                ty: TypeId::U64,
142            },
143            Op::LoadGlobal {
144                dst: "va".into(),
145                addr: "addr_a".into(),
146                ty: TypeId::I32,
147            },
148            Op::KernargLoad {
149                dst: "pb".into(),
150                offset: 8,
151                ty: TypeId::U64,
152            },
153            Op::Add {
154                dst: "addr_b".into(),
155                lhs: "pb".into(),
156                rhs: "off".into(),
157                ty: TypeId::U64,
158            },
159            Op::StoreGlobal {
160                addr: "addr_b".into(),
161                src: "va".into(),
162                ty: TypeId::I32,
163            },
164            Op::Ret,
165        ],
166        vec![
167            KernargField {
168                name: "a".into(),
169                offset: 0,
170                size: 8,
171                kind: "global_ptr".into(),
172            },
173            KernargField {
174                name: "b".into(),
175                offset: 8,
176                size: 8,
177                kind: "global_ptr".into(),
178            },
179        ],
180    )
181}
182
183/// `out[i] = global_id_x` (index write).
184pub fn tiny_index() -> Program {
185    base(
186        "tiny_index",
187        "SoftGPU-authored softgpu-sfir-v1 (index write)",
188        vec![
189            Op::GlobalId {
190                dst: "i".into(),
191                dim: 0,
192            },
193            Op::Const {
194                dst: "four".into(),
195                ty: TypeId::U64,
196                value: 4,
197            },
198            Op::Mul {
199                dst: "off".into(),
200                lhs: "i".into(),
201                rhs: "four".into(),
202                ty: TypeId::U64,
203            },
204            Op::KernargLoad {
205                dst: "p".into(),
206                offset: 0,
207                ty: TypeId::U64,
208            },
209            Op::Add {
210                dst: "addr".into(),
211                lhs: "p".into(),
212                rhs: "off".into(),
213                ty: TypeId::U64,
214            },
215            Op::StoreGlobal {
216                addr: "addr".into(),
217                src: "i".into(),
218                ty: TypeId::I32,
219            },
220            Op::Ret,
221        ],
222        vec![KernargField {
223            name: "out".into(),
224            offset: 0,
225            size: 8,
226            kind: "global_ptr".into(),
227        }],
228    )
229}
230
231/// Pack two u64 pointers into a 16-byte kernarg.
232pub fn kernarg_two_ptrs(a: u64, b: u64) -> [u8; 16] {
233    let mut k = [0u8; 16];
234    k[0..8].copy_from_slice(&a.to_le_bytes());
235    k[8..16].copy_from_slice(&b.to_le_bytes());
236    k
237}
238
239pub fn kernarg_one_ptr(p: u64) -> [u8; 8] {
240    p.to_le_bytes()
241}
242
243/// SoftGPU Phase 7: write `(wave_id * 16) + lane_id` to `out[global_id]`.
244pub fn wave_lane_ids() -> Program {
245    base(
246        "wave_lane_ids",
247        "SoftGPU-authored softgpu-sfir-v1 (Phase 7 wave/lane indexing)",
248        vec![
249            Op::GlobalId {
250                dst: "i".into(),
251                dim: 0,
252            },
253            Op::WaveId { dst: "w".into() },
254            Op::LaneId { dst: "l".into() },
255            Op::Const {
256                dst: "thousand".into(),
257                ty: TypeId::I32,
258                value: 1000,
259            },
260            Op::Mul {
261                dst: "wh".into(),
262                lhs: "w".into(),
263                rhs: "thousand".into(),
264                ty: TypeId::I32,
265            },
266            Op::Add {
267                dst: "v".into(),
268                lhs: "wh".into(),
269                rhs: "l".into(),
270                ty: TypeId::I32,
271            },
272            Op::Const {
273                dst: "four".into(),
274                ty: TypeId::U64,
275                value: 4,
276            },
277            Op::Mul {
278                dst: "off".into(),
279                lhs: "i".into(),
280                rhs: "four".into(),
281                ty: TypeId::U64,
282            },
283            Op::KernargLoad {
284                dst: "p".into(),
285                offset: 0,
286                ty: TypeId::U64,
287            },
288            Op::Add {
289                dst: "addr".into(),
290                lhs: "p".into(),
291                rhs: "off".into(),
292                ty: TypeId::U64,
293            },
294            Op::StoreGlobal {
295                addr: "addr".into(),
296                src: "v".into(),
297                ty: TypeId::I32,
298            },
299            Op::Ret,
300        ],
301        vec![KernargField {
302            name: "out".into(),
303            offset: 0,
304            size: 8,
305            kind: "global_ptr".into(),
306        }],
307    )
308}
309
310/// SoftGPU Phase 7: even lanes add 1 to `buf[i]`; odd lanes leave value unchanged.
311pub fn predicated_inc() -> Program {
312    base(
313        "predicated_inc",
314        "SoftGPU-authored softgpu-sfir-v1 (Phase 7 divergence)",
315        vec![
316            Op::GlobalId {
317                dst: "i".into(),
318                dim: 0,
319            },
320            Op::LaneId { dst: "l".into() },
321            Op::Const {
322                dst: "one".into(),
323                ty: TypeId::I32,
324                value: 1,
325            },
326            Op::Const {
327                dst: "zero".into(),
328                ty: TypeId::I32,
329                value: 0,
330            },
331            Op::And {
332                dst: "odd".into(),
333                lhs: "l".into(),
334                rhs: "one".into(),
335                ty: TypeId::I32,
336            },
337            Op::CmpEq {
338                dst: "even".into(),
339                lhs: "odd".into(),
340                rhs: "zero".into(),
341                ty: TypeId::I32,
342            },
343            Op::Const {
344                dst: "four".into(),
345                ty: TypeId::U64,
346                value: 4,
347            },
348            Op::Mul {
349                dst: "off".into(),
350                lhs: "i".into(),
351                rhs: "four".into(),
352                ty: TypeId::U64,
353            },
354            Op::KernargLoad {
355                dst: "p".into(),
356                offset: 0,
357                ty: TypeId::U64,
358            },
359            Op::Add {
360                dst: "addr".into(),
361                lhs: "p".into(),
362                rhs: "off".into(),
363                ty: TypeId::U64,
364            },
365            Op::If {
366                cond: "even".into(),
367                then_body: vec![
368                    Op::LoadGlobal {
369                        dst: "v".into(),
370                        addr: "addr".into(),
371                        ty: TypeId::I32,
372                    },
373                    Op::Add {
374                        dst: "out".into(),
375                        lhs: "v".into(),
376                        rhs: "one".into(),
377                        ty: TypeId::I32,
378                    },
379                    Op::StoreGlobal {
380                        addr: "addr".into(),
381                        src: "out".into(),
382                        ty: TypeId::I32,
383                    },
384                ],
385                else_body: vec![],
386            },
387            Op::Ret,
388        ],
389        vec![KernargField {
390            name: "buf".into(),
391            offset: 0,
392            size: 8,
393            kind: "global_ptr".into(),
394        }],
395    )
396}
397
398/// SoftGPU Phase 7: `group[lid]=lid; barrier; out[gid]=group[(lid+1)%wg]`.
399pub fn group_exchange(workgroup_x: u32) -> Program {
400    let wg = i64::from(workgroup_x);
401    base_group(
402        "group_exchange",
403        "SoftGPU-authored softgpu-sfir-v1 (Phase 7 group memory + barrier)",
404        vec![
405            Op::LocalId {
406                dst: "lid".into(),
407                dim: 0,
408            },
409            Op::GlobalId {
410                dst: "gid".into(),
411                dim: 0,
412            },
413            Op::Const {
414                dst: "four".into(),
415                ty: TypeId::U64,
416                value: 4,
417            },
418            Op::Mul {
419                dst: "goff".into(),
420                lhs: "lid".into(),
421                rhs: "four".into(),
422                ty: TypeId::U64,
423            },
424            Op::StoreGroup {
425                addr: "goff".into(),
426                src: "lid".into(),
427                ty: TypeId::I32,
428            },
429            Op::Barrier,
430            Op::Const {
431                dst: "one".into(),
432                ty: TypeId::I32,
433                value: 1,
434            },
435            Op::Const {
436                dst: "wg".into(),
437                ty: TypeId::I32,
438                value: wg,
439            },
440            Op::Add {
441                dst: "np1".into(),
442                lhs: "lid".into(),
443                rhs: "one".into(),
444                ty: TypeId::I32,
445            },
446            Op::CmpEq {
447                dst: "wrap".into(),
448                lhs: "np1".into(),
449                rhs: "wg".into(),
450                ty: TypeId::I32,
451            },
452            Op::If {
453                cond: "wrap".into(),
454                then_body: vec![Op::Const {
455                    dst: "nbr".into(),
456                    ty: TypeId::I32,
457                    value: 0,
458                }],
459                else_body: vec![Op::Add {
460                    dst: "nbr".into(),
461                    lhs: "lid".into(),
462                    rhs: "one".into(),
463                    ty: TypeId::I32,
464                }],
465            },
466            Op::Mul {
467                dst: "noff".into(),
468                lhs: "nbr".into(),
469                rhs: "four".into(),
470                ty: TypeId::U64,
471            },
472            Op::LoadGroup {
473                dst: "val".into(),
474                addr: "noff".into(),
475                ty: TypeId::I32,
476            },
477            Op::Mul {
478                dst: "ooff".into(),
479                lhs: "gid".into(),
480                rhs: "four".into(),
481                ty: TypeId::U64,
482            },
483            Op::KernargLoad {
484                dst: "p".into(),
485                offset: 0,
486                ty: TypeId::U64,
487            },
488            Op::Add {
489                dst: "addr".into(),
490                lhs: "p".into(),
491                rhs: "ooff".into(),
492                ty: TypeId::U64,
493            },
494            Op::StoreGlobal {
495                addr: "addr".into(),
496                src: "val".into(),
497                ty: TypeId::I32,
498            },
499            Op::Ret,
500        ],
501        vec![KernargField {
502            name: "out".into(),
503            offset: 0,
504            size: 8,
505            kind: "global_ptr".into(),
506        }],
507        workgroup_x * 4,
508    )
509}
510
511/// SoftGPU Phase 7: each lane `atomic_add(counter, 1)`; write previous value to `out[i]`.
512pub fn atomic_inc_reduce() -> Program {
513    use crate::ir::{AddrSpace, AtomicOrder, AtomicScope};
514    base(
515        "atomic_inc_reduce",
516        "SoftGPU-authored softgpu-sfir-v1 (Phase 7 atomics)",
517        vec![
518            Op::GlobalId {
519                dst: "i".into(),
520                dim: 0,
521            },
522            Op::Const {
523                dst: "one".into(),
524                ty: TypeId::I32,
525                value: 1,
526            },
527            Op::Const {
528                dst: "z".into(),
529                ty: TypeId::U64,
530                value: 0,
531            },
532            Op::KernargLoad {
533                dst: "pc".into(),
534                offset: 0,
535                ty: TypeId::U64,
536            },
537            Op::Add {
538                dst: "caddr".into(),
539                lhs: "pc".into(),
540                rhs: "z".into(),
541                ty: TypeId::U64,
542            },
543            Op::AtomicAdd {
544                dst: "old".into(),
545                addr: "caddr".into(),
546                src: "one".into(),
547                space: AddrSpace::Global,
548                scope: AtomicScope::Device,
549                order: AtomicOrder::Relaxed,
550            },
551            Op::Const {
552                dst: "four".into(),
553                ty: TypeId::U64,
554                value: 4,
555            },
556            Op::Mul {
557                dst: "off".into(),
558                lhs: "i".into(),
559                rhs: "four".into(),
560                ty: TypeId::U64,
561            },
562            Op::KernargLoad {
563                dst: "po".into(),
564                offset: 8,
565                ty: TypeId::U64,
566            },
567            Op::Add {
568                dst: "addr".into(),
569                lhs: "po".into(),
570                rhs: "off".into(),
571                ty: TypeId::U64,
572            },
573            Op::StoreGlobal {
574                addr: "addr".into(),
575                src: "old".into(),
576                ty: TypeId::I32,
577            },
578            Op::Ret,
579        ],
580        vec![
581            KernargField {
582                name: "counter".into(),
583                offset: 0,
584                size: 8,
585                kind: "global_ptr".into(),
586            },
587            KernargField {
588                name: "out".into(),
589                offset: 8,
590                size: 8,
591                kind: "global_ptr".into(),
592            },
593        ],
594    )
595}
596
597/// SoftGPU Phase 7: busy loop until step budget trips (watchdog).
598pub fn infinite_loop_watchdog() -> Program {
599    base(
600        "infinite_loop_watchdog",
601        "SoftGPU-authored softgpu-sfir-v1 (Phase 7 step-budget watchdog)",
602        vec![
603            Op::Const {
604                dst: "one".into(),
605                ty: TypeId::I32,
606                value: 1,
607            },
608            Op::Const {
609                dst: "tmp".into(),
610                ty: TypeId::I32,
611                value: 0,
612            },
613            Op::While {
614                cond: "one".into(),
615                body: vec![Op::Add {
616                    dst: "tmp".into(),
617                    lhs: "tmp".into(),
618                    rhs: "one".into(),
619                    ty: TypeId::I32,
620                }],
621            },
622            Op::Ret,
623        ],
624        vec![],
625    )
626}
627
628/// SoftGPU Phase 8 (negative): every workitem stores to global offset 0 (race).
629pub fn race_all_store_global_zero() -> Program {
630    base(
631        "race_all_store_global_zero",
632        "SoftGPU-authored softgpu-sfir-v1 (Phase 8 intentional global race)",
633        vec![
634            Op::Const {
635                dst: "z".into(),
636                ty: TypeId::U64,
637                value: 0,
638            },
639            Op::Const {
640                dst: "one".into(),
641                ty: TypeId::I32,
642                value: 1,
643            },
644            Op::KernargLoad {
645                dst: "p".into(),
646                offset: 0,
647                ty: TypeId::U64,
648            },
649            Op::Add {
650                dst: "addr".into(),
651                lhs: "p".into(),
652                rhs: "z".into(),
653                ty: TypeId::U64,
654            },
655            Op::StoreGlobal {
656                addr: "addr".into(),
657                src: "one".into(),
658                ty: TypeId::I32,
659            },
660            Op::Ret,
661        ],
662        vec![KernargField {
663            name: "buf".into(),
664            offset: 0,
665            size: 8,
666            kind: "global_ptr".into(),
667        }],
668    )
669}
670
671/// SoftGPU Phase 8 (negative): store at `base + (n * 4)` — one past last element.
672pub fn oob_store_past_end(n: u32) -> Program {
673    let past = i64::from(n) * 4;
674    base(
675        "oob_store_past_end",
676        "SoftGPU-authored softgpu-sfir-v1 (Phase 8 intentional OOB store)",
677        vec![
678            Op::Const {
679                dst: "off".into(),
680                ty: TypeId::U64,
681                value: past,
682            },
683            Op::Const {
684                dst: "one".into(),
685                ty: TypeId::I32,
686                value: 1,
687            },
688            Op::KernargLoad {
689                dst: "p".into(),
690                offset: 0,
691                ty: TypeId::U64,
692            },
693            Op::Add {
694                dst: "addr".into(),
695                lhs: "p".into(),
696                rhs: "off".into(),
697                ty: TypeId::U64,
698            },
699            Op::StoreGlobal {
700                addr: "addr".into(),
701                src: "one".into(),
702                ty: TypeId::I32,
703            },
704            Op::Ret,
705        ],
706        vec![KernargField {
707            name: "buf".into(),
708            offset: 0,
709            size: 8,
710            kind: "global_ptr".into(),
711        }],
712    )
713}
714
715/// SoftGPU Phase 8 (negative): group exchange without barrier (MissingBarrier).
716pub fn group_exchange_missing_barrier(workgroup_x: u32) -> Program {
717    let wg = i64::from(workgroup_x);
718    base_group(
719        "group_exchange_missing_barrier",
720        "SoftGPU-authored softgpu-sfir-v1 (Phase 8 intentional missing barrier)",
721        vec![
722            Op::LocalId {
723                dst: "lid".into(),
724                dim: 0,
725            },
726            Op::GlobalId {
727                dst: "gid".into(),
728                dim: 0,
729            },
730            Op::Const {
731                dst: "four".into(),
732                ty: TypeId::U64,
733                value: 4,
734            },
735            Op::Mul {
736                dst: "goff".into(),
737                lhs: "lid".into(),
738                rhs: "four".into(),
739                ty: TypeId::U64,
740            },
741            Op::StoreGroup {
742                addr: "goff".into(),
743                src: "lid".into(),
744                ty: TypeId::I32,
745            },
746            // Intentionally no Barrier.
747            Op::Const {
748                dst: "one".into(),
749                ty: TypeId::I32,
750                value: 1,
751            },
752            Op::Const {
753                dst: "wg".into(),
754                ty: TypeId::I32,
755                value: wg,
756            },
757            Op::Add {
758                dst: "np1".into(),
759                lhs: "lid".into(),
760                rhs: "one".into(),
761                ty: TypeId::I32,
762            },
763            Op::CmpEq {
764                dst: "wrap".into(),
765                lhs: "np1".into(),
766                rhs: "wg".into(),
767                ty: TypeId::I32,
768            },
769            Op::If {
770                cond: "wrap".into(),
771                then_body: vec![Op::Const {
772                    dst: "nid".into(),
773                    ty: TypeId::I32,
774                    value: 0,
775                }],
776                else_body: vec![Op::Add {
777                    dst: "nid".into(),
778                    lhs: "lid".into(),
779                    rhs: "one".into(),
780                    ty: TypeId::I32,
781                }],
782            },
783            Op::Mul {
784                dst: "noff".into(),
785                lhs: "nid".into(),
786                rhs: "four".into(),
787                ty: TypeId::U64,
788            },
789            Op::LoadGroup {
790                dst: "val".into(),
791                addr: "noff".into(),
792                ty: TypeId::I32,
793            },
794            Op::Mul {
795                dst: "ooff".into(),
796                lhs: "gid".into(),
797                rhs: "four".into(),
798                ty: TypeId::U64,
799            },
800            Op::KernargLoad {
801                dst: "p".into(),
802                offset: 0,
803                ty: TypeId::U64,
804            },
805            Op::Add {
806                dst: "addr".into(),
807                lhs: "p".into(),
808                rhs: "ooff".into(),
809                ty: TypeId::U64,
810            },
811            Op::StoreGlobal {
812                addr: "addr".into(),
813                src: "val".into(),
814                ty: TypeId::I32,
815            },
816            Op::Ret,
817        ],
818        vec![KernargField {
819            name: "out".into(),
820            offset: 0,
821            size: 8,
822            kind: "global_ptr".into(),
823        }],
824        workgroup_x * 4,
825    )
826}
827
828/// SoftGPU Phase 8 (negative): read group memory before any store (uninit).
829pub fn uninit_group_read() -> Program {
830    base_group(
831        "uninit_group_read",
832        "SoftGPU-authored softgpu-sfir-v1 (Phase 8 intentional uninit group read)",
833        vec![
834            Op::Const {
835                dst: "z".into(),
836                ty: TypeId::U64,
837                value: 0,
838            },
839            Op::LoadGroup {
840                dst: "v".into(),
841                addr: "z".into(),
842                ty: TypeId::I32,
843            },
844            Op::KernargLoad {
845                dst: "p".into(),
846                offset: 0,
847                ty: TypeId::U64,
848            },
849            Op::StoreGlobal {
850                addr: "p".into(),
851                src: "v".into(),
852                ty: TypeId::I32,
853            },
854            Op::Ret,
855        ],
856        vec![KernargField {
857            name: "out".into(),
858            offset: 0,
859            size: 8,
860            kind: "global_ptr".into(),
861        }],
862        4,
863    )
864}
865
866/// SoftGPU Phase 8 (negative): every workgroup stores to the same global cell.
867pub fn cross_workgroup_store_zero() -> Program {
868    base(
869        "cross_workgroup_store_zero",
870        "SoftGPU-authored softgpu-sfir-v1 (Phase 8 intentional cross-WG race)",
871        vec![
872            Op::Const {
873                dst: "z".into(),
874                ty: TypeId::U64,
875                value: 0,
876            },
877            Op::WorkgroupId {
878                dst: "w".into(),
879                dim: 0,
880            },
881            Op::KernargLoad {
882                dst: "p".into(),
883                offset: 0,
884                ty: TypeId::U64,
885            },
886            Op::Add {
887                dst: "addr".into(),
888                lhs: "p".into(),
889                rhs: "z".into(),
890                ty: TypeId::U64,
891            },
892            Op::StoreGlobal {
893                addr: "addr".into(),
894                src: "w".into(),
895                ty: TypeId::I32,
896            },
897            Op::Ret,
898        ],
899        vec![KernargField {
900            name: "buf".into(),
901            offset: 0,
902            size: 8,
903            kind: "global_ptr".into(),
904        }],
905    )
906}
907
908/// SoftGPU Phase 8 (positive): private per-lane global store (no race).
909pub fn sanitize_clean_index() -> Program {
910    tiny_index()
911}