Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Finodev #152

Merged
merged 28 commits into from
Jun 26, 2023
Merged

Finodev #152

merged 28 commits into from
Jun 26, 2023

Conversation

ashiq24
Copy link
Contributor

@ashiq24 ashiq24 commented Jun 7, 2023

No description provided.

Copy link
Member

@JeanKossaifi JeanKossaifi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @ashiq24, left some comments

if isinstance(self.output_scaling_factor, (float, int)):
self.output_scaling_factor = [self.output_scaling_factor]*self.n_dim


print("calculated out factor", self.output_scaling_factor)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add an attribute verbose (pass it in init) and only print if self.verbose:

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -195,7 +201,7 @@ def __init__(self,
use_mlp=use_mlp,
mlp_dropout=mlp_dropout,
mlp_expansion=mlp_expansion,
output_scaling_factor = self.uno_scalings[i],
output_scaling_factor = [self.uno_scalings[i]],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it a list?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Fno blocks takes scaling_factors which are 2d list
Scaling factor for each layer and scaling factor along each dims.
It can also take a scaler and also 1D list with scaling factor along each layer.

@@ -186,7 +192,7 @@ def __init__(self,

if i in self.horizontal_skips_map.keys():
prev_out = prev_out + self.uno_out_channels[self.horizontal_skips_map[i]]
print([self.uno_scalings[i]])
print(self.uno_scalings[i])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this print is necessary

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed it.

@@ -225,6 +231,7 @@ def forward(self, x):

if self.domain_padding is not None:
x = self.domain_padding.pad(x)
print(x.shape)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove this and the next print too

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

self.operator_block = operator_block
self.integral_operator = integral_operator

if self.horizontal_skips_map is None:
self.horizontal_skips_map = {}
for i in range(n_layers//2,0,):
self.horizontal_skips_map[n_layers - i -1] = i


self.output_scaling_factor = np.ones_like(self.uno_scalings[0])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's explicitly make this a list, not a tensor

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ashiq24 -- a list would be better here



self.output_scaling_factor = np.ones_like(self.uno_scalings[0])
for k in self.uno_scalings:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add some comment here, it's hard to read and understand the logic.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add some comments before merging.

self.output_scaling_factor = np.ones_like(self.uno_scalings[0])
for k in self.uno_scalings:
self.output_scaling_factor = np.multiply(self.output_scaling_factor, k)
self.output_scaling_factor = self.output_scaling_factor.tolist()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make it a list and not add additional tolist.
You can replace the np.multiply (which should work on a list anyway) with math.prod.
Actually we don't need the list, you can directly take the prod I think

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

math.prod multiply numbers in a list. but I need to multiply 2 lists. Each list specifies the scaling factors along each of the dims.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm this code is becoming very confusing - can we try to think and simplify this scaling API?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To do the scaling we need two things ---
one -- scaling factor for each layer.
two -- scaling factor along each of the dimension.
We need a two array in general.
But in case, we scale each of the dimensions with same scaling factor, then it can be a 1d array, where each element is the scaling factor for each layer.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, let's process it to always be a nested list, at the highest level and we can use zip to do the element-wise multiplication.

Do we need to have both output_scaling_factor and uno_scaling?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

@@ -480,8 +480,8 @@ def __init__(self, in_channels, out_channels, n_modes, incremental_n_modes=None,

hm1, hm2 = self.half_n_modes[0], self.half_n_modes[1]
if self.factorization is None:
self.W1 = nn.Parameter(torch.empty(self.in_channels, hm1, hm2, hm1, hm2, dtype = torch.cfloat))
self.W2 = nn.Parameter(torch.empty(self.in_channels, hm1, hm2, hm1, hm2, dtype = torch.cfloat))
self.W1 = nn.Parameter(torch.empty(hm1, hm2, hm1, hm2, dtype = torch.cfloat))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add this in a separate PR

output_pad = [int(round(i*j)) for (i,j) in zip(self.output_scale_factor,output_pad)]

if self.padding_mode == 'symmetric':
# Pad both sides
unpad_indices = (Ellipsis, ) + tuple([slice(p, -p, None) for p in output_pad ])
unpad_indices = (Ellipsis, ) + tuple([slice(p, -p, None) for p in output_pad[::-1] ])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you reverse here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first element of the output_pad pads around the last dimension. So, the first element should in the last slice.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is that the case? Shouldn't it be in the same order?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per my understanding from the documentation, it is (left, right, top, botton, front, back) for 3D tensor... Left/right padding pads along the dim = -1. Top/bottom pads along the dim = -2... and so on.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great point @ashiq24 - can we make a quick comment and point to the doc for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You meant in the code as a doc string?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, in the code just with # comment :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ashiq24 can you add a short comment here?

# if len(axis) == 1:
# return F.interpolate(x, size = new_size[0], mode = 'linear', align_corners = True)
# if len(axis) == 2:
# return F.interpolate(x, size = new_size, mode = 'bicubic', align_corners = True, antialias = True)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you comment these?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we update to still use them, they are faster

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can update this. But then the neural operator can only be used with PyTorch version later than 1.9.1. Because, " antialias" is not available in the previous distribution of PyTorch.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, let's open an issue to address this in a separate PR.

.gitignore Outdated
@@ -79,3 +79,5 @@ target/

#Ipython Notebook
.ipynb_checkpoints

setup_git.sh
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this needs to be in the main repo

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove this one.

@JeanKossaifi
Copy link
Member

Thanks @ashiq24 looks good overall but looks like the latest PR merged created a conflict, can we resolve?

@ashiq24
Copy link
Contributor Author

ashiq24 commented Jun 16, 2023

I think it now suitable for merging.

Copy link
Member

@JeanKossaifi JeanKossaifi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good overall, let's just address the comments to make the code a little clearer before merging.

output_pad = [int(round(i*j)) for (i,j) in zip(self.output_scale_factor,output_pad)]

if self.padding_mode == 'symmetric':
# Pad both sides
unpad_indices = (Ellipsis, ) + tuple([slice(p, -p, None) for p in output_pad ])
unpad_indices = (Ellipsis, ) + tuple([slice(p, -p, None) for p in output_pad[::-1] ])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ashiq24 can you add a short comment here?

.gitignore Outdated
@@ -79,3 +79,5 @@ target/

#Ipython Notebook
.ipynb_checkpoints

setup_git.sh
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove this one.

# if len(axis) == 1:
# return F.interpolate(x, size = new_size[0], mode = 'linear', align_corners = True)
# if len(axis) == 2:
# return F.interpolate(x, size = new_size, mode = 'bicubic', align_corners = True, antialias = True)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, let's open an issue to address this in a separate PR.

self.operator_block = operator_block
self.integral_operator = integral_operator

if self.horizontal_skips_map is None:
self.horizontal_skips_map = {}
for i in range(n_layers//2,0,):
self.horizontal_skips_map[n_layers - i -1] = i


self.output_scaling_factor = np.ones_like(self.uno_scalings[0])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ashiq24 -- a list would be better here



self.output_scaling_factor = np.ones_like(self.uno_scalings[0])
for k in self.uno_scalings:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add some comments before merging.

self.output_scaling_factor = np.ones_like(self.uno_scalings[0])
for k in self.uno_scalings:
self.output_scaling_factor = np.multiply(self.output_scaling_factor, k)
self.output_scaling_factor = self.output_scaling_factor.tolist()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

@JeanKossaifi
Copy link
Member

Thanks @ashiq24, it looks good - just one last thing, can you have a look at pep8?
In particular, can you remove the spaces around the =, at least in the function calls/signatures?
Good to merge aside from that.

@JeanKossaifi
Copy link
Member

Thanks @ashiq24, merging.

@JeanKossaifi JeanKossaifi merged commit 1aefe93 into neuraloperator:main Jun 26, 2023
1 check passed
@ashiq24 ashiq24 deleted the finodev branch July 22, 2023 00:51
ziqi-ma pushed a commit to ziqi-ma/neuraloperator that referenced this pull request Aug 29, 2023
* changed modules are: UNO, FNOblock, factorizedspcetralconvolution, padding layers.
* fixed the padding function, more test cases for UNO test, calculate end-to-end scaling factor from layerwise scaling factors
* Update padding.py with documentation about F.pad

Authored-by: ashiq24 <ashuiqbuet14@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants