Saturday, 2021-07-31

programmerjakelkcl: saw the llvm rfc, looks nice, though you forgot to include any links to svp64 docs01:43
lkclprogrammerjake, yeh good point. if there's followups i can post them then09:46
jnLinus Tech Tips got excited about laptop repairability and modularity:   - not like EOMA68, but a small step in the direction11:35
lkcljn: yes, the concept is kinda sinking in, finally13:08
lkclMaciejPijanowski: btw apologies for making assumptions with the NLnet grant, i was running out of time to get it in.  the tasks on the final MoU do not have to be exactly 100% what is on the application (some can be removed, but new ones cannot be added)13:13
lkclthere is plenty of time to discuss, plus (hello ghostmansd) for dmitry we can run things under the existing Grants for the next couple of months.13:14
lkclthen assuming it's approved the new Grant takes over, at a higher base rate. better for you :)13:14
ghostmansd-pcI wonder if we have a way to drop a comment in the pseudocode?16:09
ghostmansd-pcI'm now working on cbcdtd/cdtbcd, and I'd like to preserve the original notation from the specs at least in comments16:10
ghostmansd-pcHm, if I use <!-- some comment --> in pseudocode, I'm doomed, right?16:23
lkclghostmansd-pc, yes. it has to be a single line16:23
lkcl<!-- some comment16:23
lkclalso supported is python "#" comment in the pseudocode itself16:24
lkclbut do not put it at the end of a line16:24
lkcland do not include line-breaks either16:24
ghostmansd-pcAh, really? I couldn't find it in parser.16:24
lkclit's in the lexer.16:24
lkclit is reasonably standard for the lexer to be where comments are converted (and in some cases stripped out entirely)16:25
ghostmansd-pcAh, OK, I wasn't aware that not all code is in pseudo/ I haven't checked the whole directory, my bad. :-(16:25
lkclbecause, otherwise, how would the BNF / LALR parser code?16:25
lkclit would have to be like:16:25
lkcltoken comment token comment token |16:25
lkcltoken token comment token |16:26
lkcltoken comment token token |16:26
lkcltoken token token16:26
lkclan N^2 proliferation of BNF syntax entries!16:26
lkclso, it is standard practice for the _lexer_ to remove comments.16:26
ghostmansd-pcyep, I understand16:27
ghostmansd-pcI mean, I wasn't aware of the fact that lexer is decoupled in our code16:27
lkclfeel free to ask anything like that, rather than spend time yourself then, after several hours, only then ask16:27
ghostmansd-pcI haven't spent several hours on that yet :-)16:27
lkcli was lucky in that one of my lecture courses at Imperial College was in compilers.  1989?16:28
ghostmansd-pcin fact, I quickly surrendered and used <!-- --> for now, but I'll switch to #16:28
lkclactually, <--- .... --> will work just as well, but note that <!-- --> gets stripped by pagereader.py16:29
lkclwhereas "# ...." actually gets passed through to the lexer16:29
lkcl"# ...." we would expect to submit upstream to the OpenPOWER ISA WG (first submitting "#" as an addition to the notation to Section 1.3.2)16:30
lkclsigh :)16:30
ghostmansd-pcA quick question. We are going to introduce helpers for bcd/dpd conversion, if I get that correct, and use those (i.e. pseudocode won't be changed, right?). Why hadn't we created something for carry_out?16:32
lkclintroduce is slightly too strong a word... "use the existing pseudocode from the spec Appendix B.1 and B.2"16:33
lkclcarry_out, ok, so the way that SelectableInt works is to very strictly respect the bitwidth of the operations16:33
lkclso SelectableInt.__add__ goes to some lengths to (a) check its input arguments as having the same bitwidth and (b) return a result that has the exact same bitwidth16:34
lkclhow, then, when carry_out *SPECIFICALLY* returns the bit in position "LENGTH+1", could carry_out obtain that information?16:35
lkclSelectableInt.__add__ *specifically* returns a result that does *NOT* contain "1 bit more than the result of the addition"16:35
lkclit returns, "EXACTLY the length of the sum"16:35
lkclnot "EXACTLY the length of the sum plus one extra bit aka carry-bit"16:36
lkclin theory we could take the last bit and drop it into the SelectableInt as a hidden return result16:36
lkcli hate hidden return results - they're a sign of desperate "last resort"16:36
ghostmansd-pcYes, but helper could be done in terms of SelectableInt.__add__, couldn't it?16:37
lkclare you using an irc client that strips out underscores and replaces them with spaces, by any chance?16:37
lkclok so if SelectableInt.__add__ returns a result that has one more bit than is "necessary"16:38
lkclthen when that is passed to other operations, it will **FAIL**, won't it?16:38
ghostmansd-pchm, shouldn't be, I see `__add__`16:38
lkcldarn it must be hexchat. sigh16:38
lkcloperations NOT involving carry will FAIL....16:38
lkclbecause when the add result is used in subsequent operations, its length will be "LENGTH+1"16:39
lkclthat will get checked by the next operation to use that result, won't it?16:39
lkcland that operation will go, "argh, this is one bit too long, i am going to terminate this operation, catastrophically, because there is a hard error in the pseudocode"16:40
ghostmansd-pcdef carry_out(RA, RB, i):16:41
ghostmansd-pc    val = (0b0 || RA[4*i:63]) + (0b0 || RB[4*i:63]) # via concat and whatever magic16:41
ghostmansd-pc    return val[0]16:41
ghostmansd-pcCouldn't contain something like this?16:41
lkclahh ok yes, that would work16:41
lkclexcept for the i16:41
ghostmansd-pcyep, sorry for confusion16:41
lkcli like it.16:41
ghostmansd-pcthe reason I'm asking is because we actually changed the pseudocode16:42
lkcli mean, it's totally wasteful in terms of resources, to do it that way... oh wait... hang on....16:42
lkclcarry_out in the pseudocode only takes one argument16:42
lkcllook again closely16:42
ghostmansd-pcand I assumed changing the pseudocode is the least we'd like to do16:42
lkclv3.0B p11316:42
ghostmansd-pcYes, I know16:42
ghostmansd-pcwe can't be word-to-word with spec16:43
ghostmansd-pcbut at least function name would be the same16:43
lkclwhat you've proposed is *still* a change to the spec16:43
ghostmansd-pcfair enough16:43
lkclthe only way to "respect" the spec is a horrible one.16:43
ghostmansd-pcbut still it's visually closer to what it had :-)16:43
lkclto have SelectableInt.__add__ actually store bit LENGTH+1 inside a "hidden variable" SelectableInt.carry16:44
lkclthe function carry_out simply takes a copy of that variable:16:44
lkcldef carry_out(val): return SelectableInt(val.carry, 1)16:44
lkclwhich is... "hidden results".16:44
ghostmansd-pcHm. Ugly, because it changes an internal state.16:44
lkclyes.  the "last resort" method16:45
lkcli feel it's just much better to go "screw it" and remove carry_out.16:45
lkcli did that elsewhere, in the FP helpers.16:45
lkclp778 v3.0B16:45
ghostmansd-pcOK, let's keep it as is16:46
ghostmansd-pcthings would have been simpler if they had some operator instead of +16:46
ghostmansd-pcto mean exactly "+ with carry out"16:46
lkclsigh, i know16:46
ghostmansd-pcOK, sorry for distraction16:47
lkclthe entire pseudocode was never intended to be executable, more an "aide-memoire"16:47
lkclhey no problem16:47
lkclyou saw this btw?
ghostmansd-pcand thank you again for your help :-)16:47
ghostmansd-pcyep, I even fixed it and mentioned this comment :-)16:47
ghostmansd-pcI forgot to reply in the task, but I replied in the repo16:48
lkcli use git in rebase mode, i can't do "git pull" at the moment i have some outstanding uncommitted diffs16:48
lkclthe more cross-refs the better, it's not a hard rule though16:48
lkcliDCT is doing my head in :)16:49
ghostmansd-pcI usually use $(git pull --rebase)16:50
ghostmansd-pcbut yes, this assumes either committed or stashed stuff16:51
lkclrebase fails when there's uncommitted (unstashed) working modifications16:51
ghostmansd-pcwhy not stash?16:51
lkclbecause it disrupts vim file notification16:51
lkcland i run with hundreds of vim sessions, backgrounding them and jumping between them, multiple xterms16:52
lkcl"jobs | wc" returning a count of 150 is not uncommon for me16:52
lkclghostmansd-pc, index 5af6b66..63c42b2 10064417:27
lkcl looks grat17:27
ghostmansd-pcdo we have some way to convert things like [0,1,0,1] to 4-bit selectable int?17:37
ghostmansd-pcI mean, I for sure can convert list of bits to an integer and then feed selectable int with it17:39
ghostmansd-pcbut perhaps this task is quite common, and we have some wrapper or whatever17:39
lkclerrr... let me think...17:40
lkclis this inside the pseudocode?17:40
lkclbecause 0bNNNNNN syntax is supported.17:41
lkclso you would write [0,1,0,1] as simply 0b010117:41
lkcland the compiler goes, "oh, this is 4 bits, let me create a SelectableInt of width 4 for you"17:42
lkcli have to ask, why you would need that?17:43
lkclthe only reason i can think of is if you've misunderstood what the task is, with respect to BCD_TO_DPD17:44
lkclthe task there is *literally* to insert the text from the v3.0B specification into a .mdwn file17:44
lkcl"take the pseudocode from BCD_TO_DPD and convert it *BY HAND* to python"17:45
lkclif, rather, you are thinking, "converting [0,1,0,1] to 4-bit selectable int is a common task in the pseudocode", this makes no sense17:45
lkclbecause the pseudocode does not support python lists or lists of any kind17:46
lkclso that can't be it17:46
lkclselect_concat expects SelectableInts. because it has to know the bit-width.17:47
lkcl[SelectableInt(0, 1), SelectableInt(1, 1), SelectableInt(0, 1), SelectableInt(1, 1)] you would just call select_concat17:47
lkclbut the more important question is: *why* do you think it is necessary? what task are you doing where it is being considered?17:48
ghostmansd-pcI thought that we introduce a helper in Python which exactly does this: "take the pseudocode from BCD_TO_DPD and convert it *BY HAND* to python"17:54
ghostmansd-pcdo you mean that I should _expand_ BCD_TO_DPD in pseudocode?17:55
ghostmansd-pcI intended to introduce `def BCD_TO_DPD(BCD)`, which _always_ acts upon 3-digit BCD17:56
ghostmansd-pcand `def DPD_TO_BCD(DPD)`, which _always_ acts upon 10-bit BCD17:57
ghostmansd-pcand I assumed these would be called directly by pseudocode, and both will return selectable int (10-bit and 12-bit respectively)17:58
ghostmansd-pcI'm confused. The task description talks of editing; another comment mentions that I need to edit pseudocode. I don't quite get which way we should follow.18:15
ghostmansdFWIW, the code I meant to use is at bug-656 branch18:26
ghostmansdI haven't checked whether it works; that's just WIP. I thought I can check and rebase it before pushing to master after writing tests (and checking those which already exist).18:29
lkclno, definitely not: i would have said, "convert the BCD_TO_DPD function to python, by hand" if that was the case18:37
lkclbut, what would be the point? the compiler does the job already, so why would we repeat - by hand - what the compiler will do with better success?18:37
lkcland, in the process, defeat the purpose of the exercise of having a compiler which can convert the exact same code to c, later?18:38
lkclif the pseudocode is converted by hand to python (with errors), then later, the exact same work has to be done (by hand) converting to c, doesn't it?18:38
lkclwhy would we punish ourselves with such extra work?18:38
lkclno, i mean, LITERALLY copy - line-for-line, byte-for-byte, the pseudocode text from the Specification18:39
lkcland place it - line-for-line, byte-for-byte, into a .mdwn file.18:39
lkcli gave an example of where this has been done already18:39
lkclso, LITERALLY put, DIRECTLY into openpower/isafunctions/bcd.mdwn, the following contents:18:40
lkcldef BCD_TO_DPD(value):18:42
lkcl     p = (f & a & i & ¬e) | (j & a & ¬i) | (b & ¬a)18:43
lkcl     ....18:43
lkcl      .....18:43
lkclnow the only question is, what the bloody hell did IBM mean "3 bit decimal value as input"18:43
lkclah that's explained at the top of the page18:45
lkcli'll continue in the bugreport18:45
ghostmansdNot 3 bit, 3-digit18:48
ghostmansdThus 12 bits18:48
ghostmansdOne digit in BCD is 4 bits18:48
ghostmansdI'll check fpfromint18:49
ghostmansdThanks for tip18:49
ghostmansdAs is it cannot be used, by the very minimum I'll have to write some bolierplate code for a,b,c,d... variables.18:51
lkclyes.  i just went through that in the latest comment18:53
lkclif you believe it should be the other way round, i'm happy with that.  i usually get these things wrong.18:54
ghostmansdWell, I'm new to code base, so obviously you know better. I simply saw "add these to", then checked and found that it contains wrappers for some functions. By that point, I assumed this is the flow we need.18:57
ghostmansdAlso we discussed that we'd like to avoid touching pseudocode, and this made me even more confident. :-)18:57
lkclnew to the insanity known as "IBM MSB0 order", more like, sigh18:58
lkclso by "add to", i meant, "add an import which makes the results of the compiler output - the function which is created by the compiler - available to ISACaller".18:59
lkclthat means that the function op_cdtbcd (which will be created by *another* run of the compiler), will need to have, at the top, the following code:19:00
lkcl"from openpower.decodeer.isafunctions.bcd import DPD_TO_BCD, BCD_TO_DPD"19:00
lkcl(because i hate wildcard imports with a vengeance)19:01
lkcland because is responsible for writing out the op_cdtbcd function (when compiling openpower/isa/bcd.mdwn into openpower/pseudo/isa/
lkclthat import statement has to go into the template in pywriter.py19:02
lkclline 33 would do19:03
lkclit's a simple - but quite long - logical progression.19:03
lkcl* cddbcd pseudocode needs a function, DPD_TO_BCD.  how do we get that function?19:03
lkclA: auto-generate the function19:04
lkcl* yes, but how does it get to call it?19:04
lkclA: it has to be imported19:04
lkcl* yes, but how does it know where to import it from?19:04
lkclA: it doesn't -'s header has to explicitly list it19:04
lkcl* ok, but who is creating the function, DPD_TO_BCD?19:05
lkclA: the compiler, through running pyfnwriter19:05
lkcl* ok, but where does that output the function?19:05
lkclA: into openpower/decoder/isafunctions/bcd.py19:05
lkcland from there you go back up the chain.19:06
lkcl* openpower/isafunctions/bcd.mdwn contains a PSEUDOCODE definition of BCD_TO_DPD19:06
lkcl* pyfnwriter GENERATES AUTOMATICALLY openpower/decoder/isafunctions/ containing a ***PYTHON*** compiled version of BCD_TO_DPD19:07
lkcl* pywriter needs to create code **EXPLICITLY IMPORTING** that function19:07
lkcl* pywriter then outputs a header at the top of openpower/decoder/isa/ containing the import19:08
lkcland thus, when op_cdtbcd is executed, the function BCD_TO_DPD is available.19:08
lkclthis is exactly how it is done with the INT2FP function which you can see at line 4419:09
ghostmansdOk, got it19:09
lkclthen, when it comes to the pseudocode-to-c compiler, we do not have to waste time or effort duplicating INT2FP, or BCD_TO_DPD by hand-writing those functions in c.19:10
lkcljust... compile, and done.19:10
ghostmansdFeels like microcode, BTW19:10
lkclyes :)19:10
ghostmansdWhat I had in mind is closer to intrinsic, but I can see the benefits of this approach19:11
ghostmansdI'll update it19:11
ghostmansdThat's why it's in branch :-)19:11
lkclbtw, i hate branches.19:11
ghostmansdWhy so?19:11
lkclevery time i have got involved with branches, the code has been utterly wasted.19:11
lkclin a couple of cases, literally years of work19:12
ghostmansdWell, I prefer branches to couple of patches for sharing the work19:12
ghostmansdBut I guess it's a matter of personal nasal daemons19:12
ghostmansdMine are OK with branches, but, if you really don't want to deal with it, I'll send patches, this is fine19:13
lkclthey've generally made me very nervous, i prefer work in master branch.19:13
lkclpatches are a bit "yuck"19:14
lkcltypically, work that's "unused elsewhere" (like this is) is perfectly fine to drop into the master branch19:14
lkclbut, here, i can see the benefits19:14
lkclbecause it doesn't put you under pressure to run 30 minutes unit tests19:14
lkclbefore every commit19:15
lkclyou could run a comprehensive set of unit tests before doing a merge.  which would work well.19:15
lkclbtw i also made the mistake of hand-converting one of the FP functions to python.19:16
lkcli had completed it 100%, written the unit tests, then went, "arggggh what the hell am i doing??" :)19:16
lkcland the SINGLE function as well.19:17
* lkcl face-palm19:17
lkclthey were a pain in the ass, as well.  python range-end is +1 compared to IBM pseudocode.19:18
lkcli know - i'll convert them, now, so you can see what i do.19:18
lkclthen, you'll see some patches which you can track.19:18
lkcland do the same thing for BCD_2_DPD19:19
ghostmansdOk, looks fair :-)19:22
ghostmansd-pcShould I insert the pseudocode directly before these `do i = 0 to 1` lines?19:29
ghostmansd-pcI'm a bit worried about how it's generated.19:30
ghostmansd-pcWon't the functions I introduce end up inside the instruction wrapper?19:30
ghostmansd-pcboth fpfromint and double2single have no instructions inside19:31
ghostmansd-pcAh, it looks like this should be not in pseudocode section, but separately, outside of instructions.19:31
lkclehn? que?19:36
lkclcorrect, they are not instructions, they are... yes, that's why they're called helper functions19:37
lkclok now have to test the new SINGLE auto-generated function... hmmm.... that means recompiling the fpload.mdwn...19:40
lkclaaand ehhhn, wark-wark, decoder/isa/ failed.19:41
lkcli know why. forgot to create FRT (the return result)19:42
lkcli'm an idiot.  i just typed in the pseudocode for DOUBLE and called it SINGLE19:45
lkclpass.  awesome.19:45
lkclMP3 audio unit test... pass19:47
lkclDCT tests... one of which has a LD which uses DOUBLE.. pass19:48
lkclFFT.... pass19:48
lkclok all good, committing19:48
ghostmansd-pcAssertionError: line with -Form expected def BCD_TO_DPD( BCD ):19:49
ghostmansd-pcit's barking at me, but why?19:50
ghostmansd-pcI tried adding the `def BCD_TO_DPD( BCD ):` along with its code in the beginning of bcd.mdwn19:51
lkclcommit it let me take a look19:53
ghostmansd-pcsame if I add INT2FP from fpfromint19:53
ghostmansd-pcOK, will commit19:53
ghostmansd-pcwait a moment, this will break pywriter; is it acceptible?19:56
ghostmansd-pcI mean, if I commit as is19:57
ghostmansd-pchm, it looks like I must create a separate mdwn, not place in bcd.mdwn20:01
ghostmansd-pcaha, it must be in some mdwn in isafunctions, it seems20:03
lkclyes, you have to add it in... yes, that's what i wrote20:03
lkclafter removing the silliness of *yet another* non-ASCII symbol for "¬"20:04
lkclbeing used, those will need to go into openpower/isafunctions/bcd.mdwn,20:04
lkclisafunctions is helper functions20:04
lkclisa is actual instructions20:04
lkclcomment 18 is the patches i just did
lkclyes it's extremely weird, to consider actually taking lines from a processor specification and treating them as if they were executable source code20:06
lkclbut this way, it actually checks that the specification itself is correct.20:06
lkcland yes, we have found mistakes20:06
lkclmight as well re-run the main unit tests just to make absolutely sure20:10
lkclnot that there's anything related to FP in them20:10
ghostmansd-pcmmm, nice20:20
ghostmansd-pcreturn concat(a, b, c, d, e, f, g, h, i, j, k, m)20:20
ghostmansd-pcmostly what I did, lol, but this time automatically and free :-)20:20
ghostmansd-pcOK, I checked that pyfnwriter is OK, pywriter is OK with `noall bcd`, and now wait for the whole pywriter to complete20:23
ghostmansd-pcthe latter takes a while; cannot it be run in parallel, if I run it w/o args?20:25
ghostmansd-pcah, OK, it's completed; after this I also checked (though I guess there's nothing to be called, since there are no tests yet)20:26
ghostmansd-pc...anything else before I push?20:27
lkclgo for it20:40
lkcli very rarely do the full pywriter.  yes it could be, it's just usually run so rarely that i haven't made it parallel20:40
lkcli added the noall option for incremental development20:41
lkcllooks good20:42
lkcland this;a=commitdiff;h=c7fecbff307f5d4fed929d65fec35183c140040b20:42
lkclof course, sigh, i cannot guess or advise which way round return a || b || c ... will do, MSB0 or LSB0 order20:43
lkclreaallly need that documented in the concat function, sigh20:43
lkclempty lines are tolerated by pyfnwriter? huh, that's a surprise.  pywriter they're not20:47
ghostmansdI must also mention that thing dropped my lovely parentheses I added.20:47
lkclactually that may be a problem that needs resolving, due to operator precedenc20:48
ghostmansdso `((a & b) | (c & d))` got turned into `a & b | c & d`20:48
ghostmansdAnd no, please, don't tell me it's obvious, because it's not20:49
lkclthat will need sorting, by getting the compiler to output brackets manually, around expressions20:49
ghostmansdThat's actually bad, I love being explicit20:49
lkclbecause yes, it's not obvious20:49
lkclso, next would be unit tests, to make sure that the code is functionally correct.20:50
ghostmansdAnd lovely parentheses were the way for my explicitness20:50
ghostmansdThat rug really tied the room together20:50
lkclthe most obvious "simple" test is, the two instructions back-to-back20:50
ghostmansdAlso they have some examples20:51
lkclbut parenths are important because the pseudocode operator precedence rules may actually be different from python's.20:51
ghostmansdIIRC numbers 1..999?20:51
lkclwhich can be "fixed" by always outputting brackets around everything.20:51
ghostmansdI recall I saw some big table with conversion results, 0..99920:51
lkclthere are 24 combinations missing, the other way round20:52
ghostmansdI'll think about how to do the tests. Both vice versa conversion and known results are good.20:52
lkclthere's 2+ ways to do them20:52
ghostmansdAs for addg6s, I'm not sure, have to think more20:52
lkcl(1) write some code in python which does the same conversion (but do it "the obvious way" if you know what i mean)20:52
lkcl(2) just extract that table, cut/paste style, blat it into the code, and run through *all* combinations!20:53
lkclyeah, no idea even what it's for.20:53
lkclthat one, best bet is to run against qemu.20:53
lkcland hope that qemu is actually right20:53
ghostmansdWill check next week. Not sure when exactly, I suspect there will be a plethora of other things until I can allocate time.20:54
ghostmansdMost likely weekends.20:55
lkclno problem20:55
lkclgood progress20:55
ghostmansdThank you for your help and patience20:55
ghostmansdI may be tough sometimes, lol20:55
ghostmansdSorry for that20:55
lkclnot a problem20:55
lkclit's a new project, go figure20:56
ghostmansdThis addg6s is tricky. I understand what happens on the bit level, but still have no idea how and why someone might opt to use it.21:02
lkclpffh, likewise :)21:02
lkclall these three should never have been made mandatory part of the Base Compliancy Level21:02
lkclthey should have been optional as part of Decimal FP21:02
lkclwhere, for large Banking Applications, IBM would need them to sustain high-performance21:03
lkclas part of a COBOL compiler, most likely21:03
ghostmansdIIRC AMD dropped BCD instructions21:03
lkclprobably because they lost all Banking contracts to IBM21:04
ghostmansdThere was some similar stuff in x86, if I'm not mistaken21:04
lkclyeah i vaguely remember that. early 1990s?21:04
lkcli mean, back then, it *really mattered*21:05
ghostmansdI think it was upon 64 bit transition21:05
ghostmansdCan hardly imagine where it's needed except for telecom21:05
lkclif your ASCII number conversion was slow, it made your terminal slow21:05
lkclbut for Banking, they have such vast number of ASCII documents with numbers in them, it really matters21:06
ghostmansdI think we have a winner here21:06
lkcleurrgh! :)21:06
ghostmansdBut addg6s is a close competitor21:07
ghostmansdStill they at least managed to get rid of this upon 64-bit transition21:07
ghostmansdI guess we don't have this opportunity21:08
lkclnnope :)21:08
lkclbut i think it would be good to make a recommendation to the (new ISA WG) to move these to optional21:09
ghostmansdYep, totally agree21:12
ghostmansdRegarding the task you asked to check, about cavatools. I'm not the decision maker, but, as long as it's as interesting as previous tasks, I'm in. Just please keep in mind time constraints.21:12
lkcltime/cost in this case.21:13
lkcli had to put in the extra tasks because whilst they can be removed, they can't be added, once it's gone through 3rd party External Audit21:14
lkclNLnet have independent audits of proposals.21:14
ghostmansdOk then21:15
ghostmansdI'll create the team member page on the next iteration21:15

Generated by 2.17.1 by Marius Gedminas - find it at!