Open emstoudenmire opened 4 years ago
That is a neat idea. I guess if an Index doesn't have a dim=*
tag it is treated as O(1)?
Good question: actually that's where the "10" in the example above came from. I'm thinking any indices without a "dim=..." tag get their dimensions multiplied together (only counting them once for contracted indices of course), and the resulting integer gets displayed as a prefactor. We may have to take some care dealing with very large numbers, but we can use logs to handle that.
I guess the "dim=___" notation is good enough, because with the 8 character limit it still leaves 4 characters for dimension names, large enough for many common names and Greek letters (and of course one can use unicode Greek letters in Julia too...).
@mtfishman do you happen to know a good way to set up a macro environment sort of thing for this? Something like:
@showcost begin
D = A * B * C
end
Ah I didn't read carefully enough, that makes sense to report the actual dimensions of indices that don't have a "dim=*" tag.
Just a note that right now, tags do not support using greek letters. The reason is because the storage of SmallString was not made large enough for greek letters. Currently it is limited to UInt8
, while greek letters are size UInt16
:
julia> UInt8('a')
0x61
julia> UInt8('α')
ERROR: InexactError: trunc(UInt8, 945)
Stacktrace:
[1] throw_inexacterror(::Symbol, ::Type{UInt8}, ::UInt32) at ./boot.jl:557
[2] checked_trunc_uint at ./boot.jl:587 [inlined]
[3] toUInt8 at ./boot.jl:653 [inlined]
[4] UInt8 at ./boot.jl:709 [inlined]
[5] UInt8(::Char) at ./char.jl:171
[6] top-level scope at REPL[3]:1
julia> UInt16('α')
0x03b1
It may be nice to expand the storage to UInt16
to allow for greek letter tags, I would think it should not cause problems for memory/performance.
@mtfishman do you happen to know a good way to set up a macro environment sort of thing for this? Something like:
@showcost begin D = A * B * C end
It's a good question, I haven't written macros like that. I guess the question is, what do you want it to rewrite that to? I imagine something like:
setshowcost!(true)
D = A * B * C
setshowcost!(false)
I guess that should be pretty simple, since it should involve just adding the first and last lines to the code in the code block.
Or maybe something more subtle, like:
curshowcast = showcast()
setshowcost!(true)
D = A * B * C
setshowcost!(curshowcast)
since you want to keep the current state is was in. Anyway, I guess it should be pretty simple to implement that kind of macro.
Here's an idea for a useful feature we should add (could be post 1.0). We should designate a special tag syntax such as "dim=D" or "dim=chi" or possibly "|D|" or "|chi|" which, when added to an Index, says that the dimension of that Index is called "D" or "chi".
Then when two ITensors are contracted, say with three indices of dimension "chi", two indices of dimension "D", and another Index of unlabeled dimension 10, the code would report the cost as being: 10 chi^3 D^2
This report would only be shown when an option is turned on to show it, either with a macro environment, a global variable, or a function keyword argument. "showcost" could be a good name for this variable or environment name.