Skip to content

Should multi_ptr with an address space be implicitly convertible to a generic pointer? #894

@Pennycook

Description

@Pennycook

Specification Version

SYCL 2020 (Revision 10)

Section Number(s)

Issue Description

The specialization of multi_ptr for the generic address space provides two additional overloads of operator= that allow assignment from a multi_ptr with any address space:

  // Available only when:
  //   (Space == access::address_space::generic_space &&
  //    AS != access::address_space::constant_space)
  template <access::address_space AS, access::decorated IsDecorated>
  multi_ptr& operator=(const multi_ptr<value_type, AS, IsDecorated>&);

  // Available only when:
  //   (Space == access::address_space::generic_space &&
  //    AS != access::address_space::constant_space)
  template <access::address_space AS, access::decorated IsDecorated>
  multi_ptr& operator=(multi_ptr<value_type, AS, IsDecorated>&&);

The same specialization does does not provide any implicit constructors for this case, and the only way to construct a multi_ptr for the generic address space is to do so explicitly:

  // Constructors
  multi_ptr();
  multi_ptr(const multi_ptr&);
  multi_ptr(multi_ptr&&);
  explicit multi_ptr(
      typename multi_ptr<ElementType, Space, access::decorated::yes>::pointer);
  multi_ptr(std::nullptr_t);

This inconsistency may lead to some confusion, and it makes generic multi_ptr harder to use. Is it intentional?

Code Example (Optional)

#include <sycl/sycl.hpp>

void foo(sycl::multi_ptr<float, sycl::access::address_space::generic_space> GenericPointer) {
  /* some function that doesn't care about the address space */
}

void bar(sycl::multi_ptr<float, sycl::access::address_space::global_space> GlobalPointer)
{

    // This fails to compile, because there's no implicit conversion defined.
    {
        foo(GlobalPointer);
    }

    // This also fails, because the = here requires a converting constructor.
    {
        sycl::multi_ptr<float, sycl::access::address_space::generic_space> GenericPointer = GlobalPointer;
        foo(GenericPointer);
    }

    // This is (surprisingly) fine, because the = here is an overloaded assignment.
    {
        sycl::multi_ptr<float, sycl::access::address_space::generic_space> GenericPointer;
        GenericPointer = GlobalPointer;
        foo(GenericPointer);
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions