regression: `upcxx::copy(T*,global_ptr<T>,size_t)` fails to compile

Issue #405 resolved
Dan Bonachea created an issue

The upcxx::copy(T*,global_ptr<T>,size_t) overload is broken and does not compile as of 2020.3.0.

Test program:

#include <upcxx/upcxx.hpp>
#include <iostream>
#include <assert.h>

using namespace upcxx;

int main() {
  upcxx::init();

  global_ptr<int> gp = new_<int>();
  if (!rank_me()) *gp.local() = 42;
  auto gp0 = broadcast(gp,0).wait();
  global_ptr<int> gp2 = new_<int>(0);
  int *lp = gp2.local();
  copy(gp0, lp, 1).wait();
  assert(*lp == 42);
  copy(gp0, gp, 1).wait();
  assert(*gp.local() == 42);
  barrier();
  *gp.local() = 0;
  copy(lp, gp, 1).wait();
  assert(*gp.local() == 42);

  barrier();
  delete_(gp);
  delete_(gp2);
  if (!rank_me()) std::cout << "SUCCESS" << std::endl;
  upcxx::finalize();
  return 0;
}

Compile error:

In file included from /redacted/bld/upcxx.assert1.optlev0.dbgsym1.gasnet_seq.smp/include/upcxx/upcxx.hpp:10,
                 from copy-bug.cpp:1:
/redacted/bld/upcxx.assert1.optlev0.dbgsym1.gasnet_seq.smp/include/upcxx/copy.hpp: In instantiation of 'typename upcxx::detail::completions_returner<upcxx::detail::event_is_here, upcxx::detail::rput_event_values, Cxs>::return_t upcxx::copy(const T*, upcxx::global_ptr<T, KindSet>, std::size_t, Cxs) [with T = int; upcxx::memory_kind Kd = upcxx::memory_kind::host; Cxs = upcxx::completions<upcxx::future_cx<upcxx::operation_cx_event, upcxx::progress_level::user> >; typename upcxx::detail::completions_returner<upcxx::detail::event_is_here, upcxx::detail::rput_event_values, Cxs>::return_t = upcxx::future1<upcxx::detail::future_kind_shref<upcxx::detail::future_header_ops_general> >; std::size_t = long unsigned int]':
copy-bug.cpp:21:17:   required from here
/redacted/bld/upcxx.assert1.optlev0.dbgsym1.gasnet_seq.smp/include/upcxx/copy.hpp:66:65: error: invalid 'const_cast' from type 'const int*' to type 'void*'
   66 |     return detail::copy( detail::host_device, upcxx::rank_me(), const_cast<void*>(src),

This regression was introduced in ede7acbb prior to release 2020.3.0 and persists in develop. Until now we've had no tests invoking this overload, which is why it went undetected.

Comments (3)

  1. Dan Bonachea reporter

    Proposed fix in pull request #266.

    Here is the minimal patch to fix the problem:

    --- a/src/copy.hpp
    +++ b/src/copy.hpp
    @@ -63,7 +63,7 @@ namespace upcxx {
         UPCXX_ASSERT_INIT();
         UPCXX_GPTR_CHK(dest);
         UPCXX_ASSERT(src && dest, "pointer arguments to copy may not be null");
    -    return detail::copy( detail::host_device, upcxx::rank_me(), const_cast<void*>(src),
    +    return detail::copy( detail::host_device, upcxx::rank_me(), const_cast<T*>(src),
                              dest.device_, dest.rank_, dest.raw_ptr_,
                              n * sizeof(T), std::move(cxs) );
       }
    
  2. Log in to comment