On Mon, Dec 06, 2021 at 05:06:10PM +0100, Tobias Burnus wrote: > Regarding the sorting and iterators: I think we already have this problem > intrinsically – for depend/affinity, we create for <clause>(iterator(...) : > a, b) > a single loop - also to have a consistency with regards to the array bounds.
depend and affinity don't need to sort anything, we ignore affinity altogether, depend is just an unordered list of (from what we care about) addresses with the kinds next to them, it can contain duplicates etc. (and affinity if we implemented it can too). > > But if we want to put 'd' between 'a' and 'b' - we either need to split > the loop - or 'd' cannot be put between 'a' and 'b'. That's a fundamental > issue. I am not sure whether that's a real issue as all have the same map > type, but still. > > > but I'd > > prefer not to outline complex expressions from map's clause as separate > > function each, it can use many variables etc. from the parent function > > and calling those as callbacks would be too ugly. > > I concur that it would be useful to avoid using callbacks; it it seems > as if it can be avoided for iterators. I am not sure how well, but okay. > > But I have no idea how to avoid callbacks for allocatable components in > Fortran. For > > type t > type(t), allocatable :: a > end t > type(t) :: var > > (recursive type) - it is at least semi-known at compile time: > e = var; > while (e) > { map(e); e = e->a; } > I am not sure how to pass this on to the middle end - but > code for it can be generated. I bet we'd need to add a target hook for that, but other than that, I don't see why we'd need a callback at runtime. Let a target hook in first phase compute how many slots in the 3 arrays will be needed, then let's allocate the 3 arrays, fill in the static parts in there and when filling such maps follow the target hook to emit inline code that fills in those extra mappings. Note, I think it might be better to do declare mapper support before doing the recursive allocatables or Fortran polymorphism, because it will necessarily be affected by declare mapper at each level too. But generally, I don't see why whatever you want to do with a callback couldn't be done by just emitting a runtime loop that does something when filling the arrays. After all, we'll have such runtime loops even for simple iterator unless we optimize those as an array descriptor, map(iterator(i=0:n), to: *foo (i)) - in some way it is inlining what the callback would do at the GOMP_target_ext etc. caller, but it is actually the other way around, callbacks would mean outlining what can be done in mere runtime loops inside of the function that has all the vars etc. accessible there. Jakub