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

Features/372 data layout #423

Merged
merged 45 commits into from
Dec 10, 2019
Merged

Features/372 data layout #423

merged 45 commits into from
Dec 10, 2019

Conversation

ClaudiaComito
Copy link
Contributor

@ClaudiaComito ClaudiaComito commented Dec 2, 2019

Description

Addresses #372. By default, the memory layout of torch tensors is row-major (C-style), where the data are stored first dimension first (rows first in 2 dimensions). Some algorithms may run faster on a column-major memory layout (Fortran-style), where data are stored last dimension first (columns first in 2 dimensions).
In NumPy, the user can define the memory layout of an array thanks to the keyword argument order:

https://docs.scipy.org/doc/numpy/reference/generated/numpy.array.html

This PR introduces the keyword argument order for heat factories, hence the possibility of column-major memory layout for heat tensors. Currently, the default is order="C", with the possibility of specifying order="F". Because heat factories are using torch.clone() internally, and clone() does not preserve the memory layout of the tensor for the time being, I'm leaving the implementation of option order="K" for later. This issue will probably be fixed in one of the next PyTorch releases.

I'm also introducing the DNDarray properties stride (torch-like) and strides (numpy-like, output in bytes).

Fixes: #372, #403, #404

Changes proposed:

  • new function sanitize_memory_layout() in module memory
  • new kwarg order for all factories potentially giving rise to tensors with ndim > 1
  • new DNDarray properties stride(), strides (torch-like output and numpy-like output respectively)
  • new function assertTrue_memory_layout() in module basic_test

Type of change

Select relevant options.

[ ] Bug fix (non-breaking change which fixes an issue)
[x] New feature (non-breaking change which adds functionality)
[ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
[ ] Documentation update

Are all split configurations tested and accounted for?
[x] yes [ ] no
Does this change require a documentation update outside of the changes proposed?
[x] yes [ ] no
Does this change modify the behaviour of other functions?
[ ] yes [x] no
Are there code practices which require justification?
[ ] yes [x] no

…nderlying torch tensor and no longer gets the wrong info from from the numpyfied DNDarray
…ng layout (e.g. from tensor creation with ndmin > tensor.shape).
…rides already matching requested order), removed "NotImplementedError" for order K.
@codecov
Copy link

codecov bot commented Dec 6, 2019

Codecov Report

Merging #423 into master will increase coverage by 0.02%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #423      +/-   ##
==========================================
+ Coverage   98.07%   98.09%   +0.02%     
==========================================
  Files          55       55              
  Lines       11414    11548     +134     
==========================================
+ Hits        11194    11328     +134     
  Misses        220      220
Impacted Files Coverage Δ
heat/core/tests/test_dndarray.py 100% <100%> (ø) ⬆️
heat/core/tests/test_suites/test_basic_test.py 100% <100%> (ø) ⬆️
heat/core/tests/test_memory.py 100% <100%> (ø) ⬆️
heat/core/factories.py 100% <100%> (ø) ⬆️
heat/core/memory.py 100% <100%> (ø) ⬆️
heat/core/tests/test_suites/basic_test.py 100% <100%> (ø) ⬆️
heat/core/dndarray.py 95.71% <100%> (+0.05%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 4efe156...46fbc2e. Read the comment docs.

tuple of ints: bytes to step in each dimension when traversing a tensor.
numpy-like usage: self.strides
"""
stride = np.array(self._DNDarray__array.stride())
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 use torch here instead of numpy? numpy doesnt like GPUs

Copy link
Member

Choose a reason for hiding this comment

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

There is even no need to return a array (Numpy or PyTorch) at all as stride() already returns a tuple

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@krajsek this is the numpy-like version of stride (output in bytes), I need to be able to multiply it by the element size.

@coquelin77 if you expect problems I'll use list comprehension instead of numpy. Must we be wary of every numpy call then, or only when dealing with large arrays?

Copy link
Member

Choose a reason for hiding this comment

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

o.k., I see

@krajsek this is the numpy-like version of stride (output in bytes), I need to be able to multiply it by the element size.

@coquelin77 if you expect problems I'll use list comprehension instead of numpy. Must we be wary of every numpy call then, or only when dealing with large arrays?

Copy link
Member

Choose a reason for hiding this comment

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

yes, we should always be wary of using numpy. we should aim to use primarily pytorch functions. Also, if i dont misunderstand, wrapping this in a numpy array doesnt really get us anything since its already a torch tensor

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi Daniel.
This:
self._DNDarray__array.stride()
is a tuple. In order to provide numpy-like information (output in bytes), this tuple has to be multiplied by the element size of the tensor (scalar, bytes). I need to change the tuple into something that can be multiplied by a scalar. I'll use list comprehension and be done with it.

@@ -22,3 +24,44 @@ def copy(a):
return dndarray.DNDarray(
a._DNDarray__array.clone(), a.shape, a.dtype, a.split, a.device, a.comm
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 a.order to 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.

hm, but order is no tensor attribute. I'm not sure I see the need for this. The way to check the memory layout would be to call a.stride() (or a.strides if you want to be numpy-like)

krajsek
krajsek previously approved these changes Dec 9, 2019
Copy link
Member

@krajsek krajsek left a comment

Choose a reason for hiding this comment

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

I went through the code and it looks good, but I did not make test myself.

tuple of ints: bytes to step in each dimension when traversing a tensor.
numpy-like usage: self.strides
"""
stride = np.array(self._DNDarray__array.stride())
Copy link
Member

Choose a reason for hiding this comment

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

o.k., I see

@krajsek this is the numpy-like version of stride (output in bytes), I need to be able to multiply it by the element size.

@coquelin77 if you expect problems I'll use list comprehension instead of numpy. Must we be wary of every numpy call then, or only when dealing with large arrays?

@coquelin77 coquelin77 merged commit 2b03e77 into master Dec 10, 2019
@coquelin77 coquelin77 deleted the features/372-data_layout branch December 10, 2019 08:23
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.

Allow Fortran-style memory layout
3 participants