Skip to content
Closed
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
883 changes: 883 additions & 0 deletions bend2/base.bend

Large diffs are not rendered by default.

1,063 changes: 1,059 additions & 4 deletions bend2/comp.ts

Large diffs are not rendered by default.

73 changes: 73 additions & 0 deletions tests/base/array_atq.bend
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Array.atq: 4 query heads over 2 KV heads of 64, rotating 16 pairs, at
# position 5 over random caches; o (256 values, then the 4 group sums) and
# the caches' new row as F32 bits.
import Base

def bits(+v: F32) -> U32:
match v:
case F32{+w}:
U32{w}

def f32(+u: U32) -> F32:
match u:
case U32{+w}:
F32{w}

def pat(+i: U32, +s: U32) -> F32:
+h = (i * 2654435761 + s : U32)
f32(((1040187392 + h % 25165824) .|. (((h >> 7n) .&. 1) << 31n) : U32))

def fill(n: Nat, a: Array<F32>, +i: U32, +s: U32, +k: F32) -> Array<F32>:
match n:
case 0n:
a
case 1n+p:
fill(p, Array.set(F32, a, i, (pat(i, s) * k : F32)), (i + 1 : U32), s, k)

def ubits(a: Array<F32>) -> Array<U32>:
Array.map(~F32, ~U32, ~(v => bits(v)), a)

def take.k(r: Array<U32> & U32, acc: List<U32>) -> Array<U32> & List<U32>:
(a, +x) = r
(a, x <> acc)

# n slots of a ending at j, in order, onto acc.
def take(n: Nat, r: Array<U32> & List<U32>, +j: U32) -> Array<U32> & List<U32>:
match n:
case 0n:
r
case 1n+p:
(a, acc) = r
take(p, take.k(Array.get(U32, a, j), acc), (j - 1 : U32))

def show(r: Array<U32> & List<U32>) -> String:
(a, xs) = r
_ = a
List.show(~&1, ~U32, ~(v => U32.show(v)), xs)

def fbits(+n: Nat, a: Array<F32>, +i: U32) -> String:
show(take(n, (ubits(a), Nil{}), (i + U32.from_nat(n) - 1 : U32)))

def ubits.show(+n: Nat, a: Array<U32>, +i: U32) -> String:
show(take(n, (a, Nil{}), (i + U32.from_nat(n) - 1 : U32)))

def done(o: Array<F32>, y: Array<F32>, kc: Array<U32>, vc: Array<U32>, kw: Array<U32>, cs: Array<F32>) -> IO(Unit):
_ = y
_ = kw
_ = cs
do IO<Unit>:
IO.print(fbits(260n, o, 0))
IO.print(ubits.show(128n, kc, 640))
IO.print(ubits.show(128n, vc, 640))

def out(q: ((((Array<F32> & Array<U32>) & Array<U32>) & Array<U32>) & Array<F32>) & Array<F32>) -> IO(Unit):
(((((y, kc), vc), kw), cs), o) = q
done(Array.q4wait(o), y, kc, vc, kw, cs)

def main() -> IO(Unit):
out(Array.atq(fill(768n, Array.new(F32, 10n, 0.0), 0, 5, 1.0), ubits(fill(1024n, Array.new(F32, 10n, 0.0), 0, 7, 1.0)),
ubits(fill(1024n, Array.new(F32, 10n, 0.0), 0, 9, 1.0)), ubits(fill(128n, Array.new(F32, 7n, 0.0), 0, 11, 1.0)),
fill(32n, Array.new(F32, 5n, 0.0), 0, 13, 0.5), Array.new(F32, 9n, 0.0), 5, 4, 2, 64, 16, 0.000001))
#|[1049165824, 3179675648, 958332928, 1034158080, 3189702656, 929169408, 1045561344, 3191275520, 1009385472, 1053687808, 3195142144, 3182559232, 969015296, 1050345472, 3174432768, 995557376, 1050673152, 3171155968, 980418560, 1041498112, 3188916224, 1008402432, 1045889024, 3190816768, 3153657856, 1043922944, 1047789568, 3178758144, 3115253760, 1047920640, 3163488256, 993067008, 1047396352, 3146055680, 3135242240, 1041694720, 3184984064, 3096838144, 1042415616, 1043726336, 1012269056, 1047003136, 1043398656, 3175284736, 1035599872, 1044578304, 985464832, 3137929216, 1047396352, 3141402624, 3175022592, 1040252928, 3176595456, 3185704960, 1044512768, 1040646144, 3151691776, 1046609920, 1040711680, 1011810304, 3190947840, 1040515072, 3111649280, 3173384192, 1024589824, 1040908288, 3189506048, 3167682560, 3164471296, 3192324096, 1008205824, 3172925440, 1048576000, 1031798784, 3175415808, 1015873536, 3184197632, 1029701632, 1038352384, 3185508352, 1034027008, 1033175040, 3188850688, 993329152, 3168731136, 1045233664, 1021050880, 3172859904, 1044185088, 1039073280, 1033306112, 1023737856, 3182755840, 1024524288, 1032585216, 3184984064, 1027997696, 1038680064, 1040842752, 1015349248, 1024000000, 1041629184, 1032519680, 1031798784, 1044643840, 1038614528, 1021706240, 1026686976, 3166896128, 3155755008, 1037172736, 1037041664, 1031012352, 1041301504, 1032716288, 1026752512, 1035206656, 990052352, 1035403264, 1019740160, 1041367040, 1041301504, 3161063424, 1039400960, 3173646336, 3167485952, 1039204352, 1029701632, 3164405760, 1045495808, 1035010048, 1011351552, 3198746624, 1026228224, 1019215872, 3175809024, 1044250624, 3190751232, 3180920832, 1040515072, 995295232, 3188850688, 1042743296, 1033371648, 1013776384, 3196387328, 1026359296, 1011286016, 3198550016, 1018560512, 1017708544, 3176660992, 1038024704, 3162243072, 3186163712, 1040252928, 3150512128, 3189571584, 3191996416, 1026228224, 3191996416, 3196190720, 1023410176, 1011810304, 3196583936, 3160145920, 3156541440, 3181576192, 1032519680, 3135635456, 3186884608, 3188981760, 1005191168, 3197173760, 3188719616, 1023606784, 3196125184, 3189637120, 3160080384, 3154771968, 3195928576, 3161063424, 991559680, 3196649472, 1030946816, 1031995392, 3193765888, 3188588544, 3139108864, 3196780544, 3184984064, 1016791040, 1034813440, 1037697024, 3172466688, 1037172736, 3175153664, 3189374976, 1040646144, 1025638400, 1032060928, 3191078912, 1016528896, 1029177344, 3192651776, 3161194496, 1033633792, 3166896128, 1035075584, 3175350272, 3185442816, 1036779520, 3177709568, 3194290176, 1040252928, 1016856576, 1027211264, 3192717312, 3163684864, 1028784128, 3193176064, 3171614720, 3172925440, 3180789760, 1029767168, 3177185280, 3186425856, 1036386304, 3172270080, 3194486784, 3189047296, 3156934656, 3179216896, 3189374976, 3171287040, 3171090432, 3189047296, 3175284736, 1001521152, 3181707264, 3156803584, 1016135680, 3191078912, 3185639424, 3174825984, 3193962496, 3185246208, 3175153664, 1044971520, 3173646336, 3174105088, 3171024896, 3188981760, 3175350272, 1018560512, 3186491392, 1079626912, 1076530432, 3227461312, 3223059712]
#|[3188064256, 3184066560, 3147038720, 1005584384, 1024655360, 1037303808, 1044185088, 1003225088, 3131441152, 3180789760, 1045168128, 3137470464, 3132620800, 1039335424, 3173646336, 3140616192, 1048051712, 3171811328, 3181182976, 1035665408, 1035599872, 3170959360, 1000472576, 1037107200, 3163291648, 3215327232, 3152478208, 3171024896, 3163881472, 1050017792, 3160408064, 3172401152, 1060241408, 3181182976, 1050083328, 1040187392, 3187408896, 1054277632, 3209625600, 3191406592, 1034289152, 3206414336, 1048969216, 3187933184, 3210674176, 1054474240, 3200319488, 1043333120, 1059323904, 3205300224, 1049231360, 3202875392, 3185901568, 1053294592, 3199860736, 1043005440, 3180593152, 3205562368, 1047789568, 3178299392, 1062207488, 1053097984, 3199336448, 1042087936, 3178102784, 3146973184, 998703104, 1017905152, 3170959360, 1028063232, 1059127296, 3149594624, 3122135040, 3214082048, 3190489088, 3127640064, 1006698496, 1041367040, 3135373312, 992149504, 1038024704, 3176660992, 1032454144, 1050607616, 3181510656, 3196649472, 1016856576, 3183149056, 3152805888, 3168731136, 998572032, 3160735744, 1040384000, 1043202048, 3167223808, 1023344640, 1050542080, 1032060928, 1048838144, 1054932992, 1037631488, 1069678592, 1059979264, 1042612224, 1049231360, 1057619968, 1038680064, 1029963776, 1061748736, 1043922944, 1051459584, 1041367040, 1049690112, 1055981568, 1064304640, 1053884416, 1036189696, 1068695552, 1050345472, 1033306112, 3195731968, 1056702464, 1037631488, 1028521984, 1060765696, 1042612224, 1050542080, 1057226752]
#|[3199220357, 1046983734, 3206491623, 3201738648, 1049502025, 3209009914, 3204256939, 1043631708, 1064044557, 3206775230, 1046149999, 1041397024, 3200904913, 3196151938, 1043915315, 3203423204, 3198670229, 1046433606, 3205941495, 3201188520, 1040563289, 1060976138, 3203706811, 1043081580, 1063494429, 3197836494, 1045599871, 1040846896, 3200354785, 3195601810, 1043365187, 3202873076, 3198120101, 1062660694, 1057907719, 3200638392, 1065178985, 1060426010, 3203156683, 1042531452, 1062944301, 3197286366, 3192533391, 1040296768, 3199804657, 3195051682, 1059592275, 1054839300, 3197569973, 1062110566, 1057357591, 3200088264, 1064628857, 1059875882, 3194217947, 3189464972, 1062394173, 3196736238, 3191983263, 1064912464, 1051770881, 3194501554, 1059042147, 1054289172, 3197019845, 1061560438, 1056807463, 3191149528, 3211562377, 1059325754, 3193667819, 3188914844, 1061844045, 3196186110, 3191433135, 1055973728, 1051220753, 3193951426, 1058492019, 1053739044, 3188081109, 3208493958, 1056257335, 3190599400, 3211012249, 1058775626, 3193117691, 3188364716, 1052905309, 1048152334, 3190883007, 1055423600, 1050670625, 3193401298, 3205425539, 1053188916, 3212696805, 3207943830, 1055707207, 3190049272, 3210462121, 1049836890, 1045083915, 3187814588, 1052355181, 1047602206, 3190332879, 3202357120, 1050120497, 3209628386, 3204875411, 1052638788, 3212146677, 3207393702, 1046768471, 1042015496, 3209911993, 1049286762, 1044533787, 3212430284, 1051805053, 1047052078, 3206559967, 3201806992, 1049570369, 3209078258, 3204325283, 1052088660]
76 changes: 76 additions & 0 deletions tests/base/array_gdn.bend
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Array.gdn: two value heads of 64 rows over key heads of 32 (c = 256,
# din = 128); o (128 values, then the 2 group sums), 64 state values (rounded
# to bfloat16: Metal's sums move their last bits) and 64 window values as F32
# bits. a and dt are halved, the state quartered.
import Base

def bits(+v: F32) -> U32:
match v:
case F32{+w}:
U32{w}

def f32(+u: U32) -> F32:
match u:
case U32{+w}:
F32{w}

def pat(+i: U32, +s: U32) -> F32:
+h = (i * 2654435761 + s : U32)
f32(((1040187392 + h % 25165824) .|. (((h >> 7n) .&. 1) << 31n) : U32))

def fill(n: Nat, a: Array<F32>, +i: U32, +s: U32, +k: F32) -> Array<F32>:
match n:
case 0n:
a
case 1n+p:
fill(p, Array.set(F32, a, i, (pat(i, s) * k : F32)), (i + 1 : U32), s, k)

def ubits(a: Array<F32>) -> Array<U32>:
Array.map(~F32, ~U32, ~(v => bits(v)), a)

def take.k(r: Array<U32> & U32, acc: List<U32>) -> Array<U32> & List<U32>:
(a, +x) = r
(a, x <> acc)

# n slots of a ending at j, in order, onto acc.
def take(n: Nat, r: Array<U32> & List<U32>, +j: U32) -> Array<U32> & List<U32>:
match n:
case 0n:
r
case 1n+p:
(a, acc) = r
take(p, take.k(Array.get(U32, a, j), acc), (j - 1 : U32))

def show(r: Array<U32> & List<U32>) -> String:
(a, xs) = r
_ = a
List.show(~&1, ~U32, ~(v => U32.show(v)), xs)

def fbits(+n: Nat, a: Array<F32>, +i: U32) -> String:
show(take(n, (ubits(a), Nil{}), (i + U32.from_nat(n) - 1 : U32)))

def ubits.show(+n: Nat, a: Array<U32>, +i: U32) -> String:
show(take(n, (a, Nil{}), (i + U32.from_nat(n) - 1 : U32)))

def done(o: Array<F32>, y: Array<F32>, w: Array<F32>, s: Array<F32>, cw: Array<U32>, ab: Array<U32>, sn: Array<U32>) -> IO(Unit):
_ = y
_ = cw
_ = ab
_ = sn
do IO<Unit>:
IO.print(fbits(130n, o, 0))
IO.print(fbits(64n, Array.map(~F32, ~F32, ~(v => Array.q4mv.round(v)), s), 1000))
IO.print(fbits(64n, w, 200))

def out(q: (((((Array<F32> & Array<F32>) & Array<F32>) & Array<U32>) & Array<U32>) & Array<U32>) & Array<F32>) -> IO(Unit):
((((((y, w), s), cw), ab), sn), o) = q
done(Array.q4wait(o), y, w, s, cw, ab, sn)

def main() -> IO(Unit):
out(Array.gdn(fill(388n, Array.new(F32, 9n, 0.0), 0, 5, 1.0), fill(768n, Array.new(F32, 10n, 0.0), 0, 7, 1.0),
fill(4096n, Array.new(F32, 12n, 0.0), 0, 9, 0.25), ubits(fill(1024n, Array.new(F32, 10n, 0.0), 0, 11, 0.5)),
ubits(fill(4n, Array.new(F32, 2n, 0.0), 0, 13, 0.5)), ubits(fill(64n, Array.new(F32, 6n, 0.0), 0, 17, 1.0)),
Array.new(F32, 8n, 0.0), 256, 32, 64, 2, 128, 64, 0.000001))
#|[3170238464, 3168468992, 3163750400, 3172532224, 1015742464, 3167223808, 1057882112, 1035403264, 3165847552, 3204186112, 3184984064, 3165126656, 994836480, 3180265472, 1023475712, 1024065536, 3191668736, 3174498304, 1021050880, 3185508352, 1020526592, 3153657856, 1045692416, 1040384000, 3153592320, 3205758976, 1040384000, 3159359488, 1001586688, 3168731136, 1012269056, 3163553792, 3179479040, 3167027200, 3164864512, 3187736576, 1017643008, 984743936, 1037959168, 3179544576, 3148349440, 3199926272, 3185704960, 3155886080, 991166464, 1021378560, 996081664, 1010368512, 3147563008, 3163750400, 3186819072, 3185836032, 3171352576, 1024000000, 1025966080, 1018167296, 998440960, 3178627072, 3185770496, 3160080384, 1023606784, 1011548160, 1007747072, 1017380864, 3169386496, 3173777408, 3156606976, 3192913920, 3172925440, 3172401152, 1032716288, 3184656384, 3158966272, 3200712704, 3175022592, 3153330176, 3164340224, 3164798976, 1011286016, 3160670208, 3191013376, 1013841920, 1016266752, 1010565120, 3153199104, 1015414784, 1043136512, 3182100480, 3161653248, 1042677760, 1037238272, 3125346304, 3168337920, 1016856576, 3144548352, 1028849664, 3178168320, 1025769472, 1022099456, 1025835008, 3180068864, 3130327040, 3171549184, 1030815744, 3150381056, 1025638400, 1013776384, 1000341504, 3163160576, 1007157248, 3149660160, 1025114112, 3160670208, 990052352, 1015087104, 1020985344, 1023213568, 1042087936, 1022099456, 1024393216, 3158573056, 3176333312, 3152216064, 1002831872, 1015414784, 1032650752, 994312192, 1037631488, 3216881920, 3188944640]
#|[1043922944, 1030750208, 3173580800, 3185573888, 1033240576, 3176071168, 3187933184, 1035665408, 3195404288, 3190554624, 1038221312, 1025245184, 3193110528, 1040646144, 1027866624, 3195666432, 3182428160, 1030029312, 3172859904, 3185049600, 1032585216, 3175350272, 3187671040, 1035141120, 1047265280, 3189964800, 1037500416, 1024065536, 3192717312, 1030946816, 1026490368, 3195207680, 3181838336, 1029373952, 3172794368, 3184394240, 1032060928, 1044185088, 3186950144, 1034289152, 1046740992, 3189440512, 1027932160, 1024393216, 3191996416, 3179610112, 1027014656, 3194552320, 3181248512, 1028390912, 1041039360, 3183935488, 1031274496, 1043726336, 3186622464, 1033895936, 1047527424, 3188457472, 3166699520, 1049362432, 3189833728, 3161194496, 1032519680, 1039794176]
#|[1053868879, 1049115904, 3191846577, 1056387170, 1051634195, 3211142084, 1058905461, 1054152486, 3188494551, 3208907400, 1056670777, 3191012842, 3211425691, 1050800460, 3193531133, 3188778158, 1053318751, 1048565776, 3208073665, 1055837042, 1051084067, 3210591956, 3205838981, 1053602358, 3187944423, 3208357272, 1047732041, 3190462714, 3210875563, 1050250332, 1045497357, 3205005246, 1052768623, 1048015648, 3207523537, 3202770562, 1050533939, 3210041828, 3205288853, 1044663622, 3212560119, 3207807144, 1047181913, 1042428938, 3210325435, 1049700204, 1044947229, 3204455118, 1052218495, 1047465520, 3206973409, 3202220434, 1041595203, 3209491700, 3204738725, 1044113494, 1064526343, 3207257016, 1046631785, 1041878810, 3201386699, 1049150076, 1044397101, 3203904990]
55 changes: 55 additions & 0 deletions tests/base/array_q4go.bend
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Array.q4go + Array.q4wait: the 13x128 case of array_q4mv.bend through the
# queue (rows 0 .. 12, then rows 3 .. 8 alone). w and y stay live until after
# the wait, because a queued product reads w and writes y until then. Slots it
# does not write keep 7.0 (1088421888). Without a Metal heap, q4go is q4mv and
# q4wait is the identity.
import Base

def bits(+v: F32) -> U32:
match v:
case F32{+w}:
U32{w}

def wset(n: Nat, a: Array<U32>, +i: U32) -> Array<U32>:
match n:
case 0n:
a
case 1n+p:
+s = (15360 + (i % 8) * 17 + ((15488 + (i % 5) * 19) << 16n) : U32)
+b = (48128 + (i % 6) * 23 + ((15232 + (i % 7) * 13) << 16n) : U32)
wset(p, Array.set(U32, Array.set(U32, a, (208 + i : U32), s), (221 + i : U32), b), (i + 1 : U32))

def cset(n: Nat, a: Array<U32>, +i: U32) -> Array<U32>:
match n:
case 0n:
wset(13n, a, 0)
case 1n+p:
cset(p, Array.set(U32, a, i, (i * 2654435761 + 12345 : U32)), (i + 1 : U32))

def xset(n: Nat, a: Array<F32>, +j: U32) -> Array<F32>:
match n:
case 0n:
Array.set(F32, Array.set(F32, a, 128, 1.5), 129, 2.5)
case 1n+p:
xset(p, Array.set(F32, a, j, ((U32.to_f32((j % 7 : U32)) - 3.0) * 0.25 : F32)), (j + 1 : U32))

def show.fin(w: Array<U32>, s: String) -> String:
_ = w
s

# w is dropped after y is read: a queued product reads w until the wait.
def show.k(w: Array<U32>, x: Array<F32>, y: Array<F32>) -> String:
_ = x
show.fin(w, List.show(~&1, ~U32, ~(v => U32.show(v)), Array.to_list(~U32, Array.map(~F32, ~U32, ~(v => bits(v)), y))))

def show(q: (Array<U32> & Array<F32>) & Array<F32>) -> String:
((w, x), y) = q
show.k(w, Array.q4wait(x), y)

def main() -> IO(Unit):
do IO<Unit>:
IO.print(show(Array.q4go(cset(208n, Array.new(U32, 8n, 0), 0), xset(128n, Array.new(F32, 8n, 0.0), 0), Array.new(F32, 4n, 7.0), 0, 13, 128, 13)))
IO.print(show(Array.q4go(cset(208n, Array.new(U32, 8n, 0), 0), xset(128n, Array.new(F32, 8n, 0.0), 0), Array.new(F32, 4n, 7.0), 3, 6, 128, 13)))

#|[3190161408, 1045233664, 1059061760, 3189637120, 3178823680, 1039532032, 1043202048, 3171614720, 3194748928, 3205890048, 1055129600, 1045954560, 3183542272, 1088421888, 1088421888, 1088421888]
#|[1088421888, 1088421888, 1088421888, 3189637120, 3178823680, 1039532032, 1043202048, 3171614720, 3194748928, 1088421888, 1088421888, 1088421888, 1088421888, 1088421888, 1088421888, 1088421888]
44 changes: 44 additions & 0 deletions tests/base/array_q4mv.bend
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Array.q4mv: 13 rows of 128 weights (one block of eight rows and a tail
# of five), then rows 3 .. 8 alone; outputs as F32 bits, slots it does not
# write keep 7.0 (1088421888)
import Base

def bits(+v: F32) -> U32:
match v:
case F32{+w}:
U32{w}

def wset(n: Nat, a: Array<U32>, +i: U32) -> Array<U32>:
match n:
case 0n:
a
case 1n+p:
+s = (15360 + (i % 8) * 17 + ((15488 + (i % 5) * 19) << 16n) : U32)
+b = (48128 + (i % 6) * 23 + ((15232 + (i % 7) * 13) << 16n) : U32)
wset(p, Array.set(U32, Array.set(U32, a, (208 + i : U32), s), (221 + i : U32), b), (i + 1 : U32))

def cset(n: Nat, a: Array<U32>, +i: U32) -> Array<U32>:
match n:
case 0n:
wset(13n, a, 0)
case 1n+p:
cset(p, Array.set(U32, a, i, (i * 2654435761 + 12345 : U32)), (i + 1 : U32))

def xset(n: Nat, a: Array<F32>, +j: U32) -> Array<F32>:
match n:
case 0n:
Array.set(F32, Array.set(F32, a, 128, 1.5), 129, 2.5)
case 1n+p:
xset(p, Array.set(F32, a, j, ((U32.to_f32((j % 7 : U32)) - 3.0) * 0.25 : F32)), (j + 1 : U32))

def show(q: (Array<U32> & Array<F32>) & Array<F32>) -> String:
((w, x), y) = q
List.show(~&1, ~U32, ~(v => U32.show(v)), Array.to_list(~U32, Array.map(~F32, ~U32, ~(v => bits(v)), y)))

def main() -> IO(Unit):
do IO<Unit>:
IO.print(show(Array.q4mv(cset(208n, Array.new(U32, 8n, 0), 0), xset(128n, Array.new(F32, 8n, 0.0), 0), Array.new(F32, 4n, 7.0), 0, 13, 128, 13)))
IO.print(show(Array.q4mv(cset(208n, Array.new(U32, 8n, 0), 0), xset(128n, Array.new(F32, 8n, 0.0), 0), Array.new(F32, 4n, 7.0), 3, 6, 128, 13)))

#|[3190161408, 1045233664, 1059061760, 3189637120, 3178823680, 1039532032, 1043202048, 3171614720, 3194748928, 3205890048, 1055129600, 1045954560, 3183542272, 1088421888, 1088421888, 1088421888]
#|[1088421888, 1088421888, 1088421888, 3189637120, 3178823680, 1039532032, 1043202048, 3171614720, 3194748928, 1088421888, 1088421888, 1088421888, 1088421888, 1088421888, 1088421888, 1088421888]
Loading
Loading