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

Design of Matrix class #1089

Closed
kkarbowiak opened this issue Apr 17, 2024 · 7 comments
Closed

Design of Matrix class #1089

kkarbowiak opened this issue Apr 17, 2024 · 7 comments
Assignees
Labels
Milestone

Comments

@kkarbowiak
Copy link
Contributor

Looks like the design of Matrix class could be improved. Here are some points:

  1. Matrix is a template class, but is only instantiated for uint32_t (in fact it's UserCost, UserDuration and UserDistance, but all boil down to the same type).
  2. The implementation is partly in source file, which requires explicit template instantiation (see:
    template class Matrix<UserCost>;
    ) to prevent linking errors. The instantation is for UserCost, which automatically works for UserDuration and UserDistance due to all three being an alias for uint32_t. Adding explicit instantiation for the latter two types for clarity results in compiler error (duplicate explicit instantiation of ‘class vroom::Matrix<unsigned int>’).
  3. Trying to reuse the class for any other type is not possible due to linker errors.
  4. The constructors could be cleaned up a bit.

I propose to leave Matrix as a template class but move the implementation entirely to the header file.

@kkarbowiak
Copy link
Contributor Author

Looks like there are some other template functions implemented in source files together with explicit template instantiation, e.g.

template bool
TWRoute::is_valid_addition_for_tw(const Input& input,
const Amount& delivery,
const std::vector<Index>::iterator first_job,
const std::vector<Index>::iterator last_job,
const Index first_rank,
const Index last_rank,
bool check_max_load) const;
template bool TWRoute::is_valid_addition_for_tw(
const Input& input,
const Amount& delivery,
const std::vector<Index>::reverse_iterator first_job,
const std::vector<Index>::reverse_iterator last_job,
const Index first_rank,
const Index last_rank,
bool check_max_load) const;
template bool TWRoute::is_valid_addition_for_tw(
const Input& input,
const Amount& delivery,
const std::array<Index, 1>::const_iterator first_job,
const std::array<Index, 1>::const_iterator last_job,
const Index first_rank,
const Index last_rank,
bool check_max_load) const;
template bool TWRoute::is_valid_addition_for_tw(
const Input& input,
const Amount& delivery,
const std::vector<Index>::const_iterator first_job,
const std::vector<Index>::const_iterator last_job,
const Index first_rank,
const Index last_rank,
bool check_max_load) const;
template void TWRoute::replace(const Input& input,
const Amount& delivery,
const std::vector<Index>::iterator first_job,
const std::vector<Index>::iterator last_job,
const Index first_rank,
const Index last_rank);
template void
TWRoute::replace(const Input& input,
const Amount& delivery,
const std::vector<Index>::const_iterator first_job,
const std::vector<Index>::const_iterator last_job,
const Index first_rank,
const Index last_rank);
template void
TWRoute::replace(const Input& input,
const Amount& delivery,
const std::vector<Index>::reverse_iterator first_job,
const std::vector<Index>::reverse_iterator last_job,
const Index first_rank,
const Index last_rank);
template void
TWRoute::replace(const Input& input,
const Amount& delivery,
const std::array<Index, 1>::const_iterator first_job,
const std::array<Index, 1>::const_iterator last_job,
const Index first_rank,
const Index last_rank);

What is the intention of this?

@kkarbowiak kkarbowiak mentioned this issue Apr 17, 2024
2 tasks
@jcoupey jcoupey added this to the v1.15.0 milestone Apr 25, 2024
@jcoupey
Copy link
Collaborator

jcoupey commented Apr 25, 2024

I propose to leave Matrix as a template class but move the implementation entirely to the header file.

Makes sense. As I understand it, this will allow the direct template instantiation in compilation units using the Matrix class, along with potential compiler optimizations.

@jcoupey
Copy link
Collaborator

jcoupey commented Apr 25, 2024

The other explicit template instantiation occurrences (TWRoute::is_valid_addition_for_tw and the likes) are meant to allow using those functions in a wide range of contexts with const/non-const foward/reverse iterators. Happy to discuss a better way to do it. Obviously #1090 could make this simpler too.

@kkarbowiak
Copy link
Contributor Author

I propose to leave Matrix as a template class but move the implementation entirely to the header file.

Makes sense. As I understand it, this will allow the direct template instantiation in compilation units using the Matrix class, along with potential compiler optimizations.

Exactly this.

@kkarbowiak
Copy link
Contributor Author

kkarbowiak commented Apr 26, 2024

The other explicit template instantiation occurrences (TWRoute::is_valid_addition_for_tw and the likes) are meant to allow using those functions in a wide range of contexts with const/non-const foward/reverse iterators.

This I understand.

Happy to discuss a better way to do it. Obviously #1090 could make this simpler too.

A common practice is to implement template functions in header files. This allows the compiler to instantiate the template as needed in translation units and avoids the need for explicit template instantiations. Potential drawbacks include increased compilation time and increased binary size.

I did not make myself clear but I meant to ask whether there was any reason to have the implementation in source file (with explicit template instantiation) as opposed to have the implementation in header file.

@jcoupey
Copy link
Collaborator

jcoupey commented Apr 26, 2024

whether there was any reason to have the implementation in source file (with explicit template instantiation) as opposed to have the implementation in header file

I kind of made it this way to keep some level of separation between definition in headers and actual implementation. I have no strong feeling about this though and there are other situations where we moved things to the headers for optimization purposes. Yet, the implementation for TWRoute::replace and TWRoute::is_valid_addition_for_tw being much bigger, I guess I'd be a bit more hesitant to move them to the header than with the Matrix class. I realize this is rather subjective.

@jcoupey
Copy link
Collaborator

jcoupey commented Apr 29, 2024

Done in #1091.

@jcoupey jcoupey closed this as completed Apr 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants