Prev: reshape efficiency
Next: parameter incosistency
From: glen herrmannsfeldt on 19 May 2010 18:42 Richard Maine <nospam(a)see.signature> wrote: (snip) > Note, in case you are unclear on the nature of his question, that he > stated that my post answered it, which I take as pretty good evidence > that I understood the question. It seems that there are two questions. First, about the size of the VECTOR component. Second, as the OP says: "However, I don't want to insert allocate statement for each variables of User_Data as there are many such types in the overall program." It doesn't seem that array tricks really help solve that one, but it seemed that there was a suggestion that such tricks couldn't be used with arrays of structures. The sample only has x, y(10), and z(10,100), but maybe the real program has many more variables, maybe a lot of arrays. Also, just to be sure, for allocatable components of an array of structure, you have to separately (with a loop) allocate each one? It seems right, but I haven't tried it. -- glen
From: Ron Shepard on 19 May 2010 19:50 In article <ht1phi$ai4$1(a)speranza.aioe.org>, glen herrmannsfeldt <gah(a)ugcs.caltech.edu> wrote: > Also, just to be sure, for allocatable components of an array of > structure, you have to separately (with a loop) allocate each one? > It seems right, but I haven't tried it. I think so, but it doesn't seem very hard to do. You could write a subroutine that allocates all of the array components with the appropriate sizes, and then just call that subroutine within a loop for each element of the arrays. This is the same amount of runtime effort that would occur if the language did it automatically, so the only extra effort on the programmer is setting up the loops for each of the arrays. call user_data_allocate(n,x) do i = 1, 30 call user_data_allocate(n,y(i)) enddo do j = 1, 10 do i = 1, 100 call user_data_allocate(n,z(i,j)) enddo enddo One should replace the constants with the appropriate parameters, or use lbound() and ubound(), to generalize it and make it easier to change things, but that's all there is to it. If there is only one allocatable vector in the structure, then you could skip the subroutine and just put the appropriate allocate() statement inside the loop. One possibility to shorten things might be to write an elemental subroutine that does the allocations, and call that subroutine with a scalar or array of arbitrary rank. call user_data_allocate(n,x) call user_data_allocate(n,y) call user_data_allocate(n,z) Is that possible? It would be the same runtime effort, just a little less code for the programmer to write. But I don't know if memory allocation is one of the allowed side effects in elemental subroutines. $.02 -Ron Shepard
From: Richard Maine on 19 May 2010 21:19 glen herrmannsfeldt <gah(a)ugcs.caltech.edu> wrote: > It doesn't seem that array tricks really help solve that one, but > it seemed that there was a suggestion that such tricks couldn't > be used with arrays of structures. That's not how I read Gordon's comment. Perhaps that's partly influenced by my being pretty sure that he would know better than to make such strange claim, while it made perfect sense in the context of talking about components. > Also, just to be sure, for allocatable components of an array of > structure, you have to separately (with a loop) allocate each one? Yes. Well, unless you are using the f2003 allocate-on-assignment thing, which would also apply to assignment of the whole thing. -- Richard Maine | Good judgment comes from experience; email: last name at domain . net | experience comes from bad judgment. domain: summertriangle | -- Mark Twain
From: Ron Shepard on 20 May 2010 01:00 In article <ron-shepard-B227A6.18505719052010(a)news60.forteinc.com>, Ron Shepard <ron-shepard(a)NOSPAM.comcast.net> wrote: [...] > One possibility to shorten things might be to write an elemental > subroutine that does the allocations, and call that subroutine with a > scalar or array of arbitrary rank. > > call user_data_allocate(n,x) > call user_data_allocate(n,y) > call user_data_allocate(n,z) > > Is that possible? It would be the same runtime effort, just a little > less code for the programmer to write. But I don't know if memory > allocation is one of the allowed side effects in elemental subroutines. Here is what I had in mind: program test_elem implicit none type user_data integer, allocatable :: vector(:) end type user_data integer :: n=7 type(user_data) :: x, y(10), z(100,10) call user_data_allocate(n,x) call user_data_allocate(n,y) call user_data_allocate(n,z) write(*,*) 'size=', size(x%vector), size(y(5)%vector), & & size(z(50,5)%vector) contains elemental subroutine user_data_allocate(n,w) integer, intent(in) :: n type(user_data),intent(inout) :: w allocate(w%vector(n)) return end subroutine user_data_allocate end program test_elem Is this all legal? If so, then it seems to address this problem in a simple and concise way. $.02 -Ron Shepard
From: Jim Xia on 20 May 2010 09:25
> But he specifically said that he wanted to input the value at run time. > That was the whole point of the original question. He already knew and > was using the *MUCH* simpler f95 way to do it at compile time. Because > all the values in a particular execution were the same (as I think was > mentioned in the previous thread), doing it at compile time doesn't > involve PDTs at all. You just use a named constant to specify the > dimension, as in his original f95 code. > > That's why I just showed a LEN parameter without bothering to discuss > the alternative - the LEN parameter fit the stated problem, while a KIND > parameter doesn't. Admitedly, there could be other problems that the > KIND parameter could solve. If you wanted to allow different variables > to have different values of the parameter, but those values were known > at compile time, then a KIND parameter would be appropriate. Ah, yes. I misunderstood the original question -- got sidetracked by other posts. In that case, LEN type parameter is a right choice. However for your declaration type(user_data(n)) :: x, y(30),z(100,10) assumes: either N is a named constant which leads to a compile time known value or N is a specification expression where x has to be used in a subroutine or function. I'd suggest to use deferred length type parameter as follows type(user_data(:)), allocatable :: x For allocating all the parameterized components, you need only one allcoate statement, instead of one allocate statement for each component allocate (user_data(N) :: x) Cheers, Jim |