Refactor fill-case of md_copy2
@@ -644,6 +644,68 @@ void md_copy2(unsigned int D, const long dim[D], const long ostr[D], void* optr,
#ifdef USE_CUDA
bool use_gpu = cuda_ondevice(optr) || cuda_ondevice(iptr);
+
+#if 1
+ // less calls for filling-like copies
+
+ long tostr_fill[D];
+ long tistr_fill[D];
+ long tdims_fill[D];
+
+ md_copy_strides(D, tostr_fill, ostr);
+ md_copy_strides(D, tistr_fill, istr);
+ md_copy_dims(D, tdims_fill, dim);
+
+ long (*nstr2_fill[2])[D] = { &tostr_fill, &tistr_fill };
+
+ int ND_fill = simplify_dims(2, D, tdims_fill, nstr2_fill);
+
+ bool fill = (2 == ND_fill) || (1 == ND_fill);
+
+ size_t cp_size = 0;
+ unsigned long repetitions = 0;
+
+ if (2 == ND_fill) {
+
+ fill = fill && ((*nstr2_fill[0])[0] == (signed)size);
+ fill = fill && ((*nstr2_fill[1])[0] == (signed)size);
+
+ cp_size = tdims_fill[0] * size;
+ repetitions = tdims_fill[1];
+
+ fill = fill && ((*nstr2_fill[0])[1] == (signed)cp_size);
+ fill = fill && ((*nstr2_fill[1])[1] == 0);
+ }
+
+ if (1 == ND_fill) {
+
+ fill = fill && ((*nstr2_fill[0])[0] == (signed)size);
+ fill = fill && ((*nstr2_fill[1])[0] == 0);
+
+ cp_size = size;
+ repetitions = tdims_fill[0];
+ }
+
+ if (use_gpu && fill) {
+
+ cuda_memcpy(cp_size, optr, iptr);
+
+ unsigned int i = 1;
+
+ while (2 * i <= repetitions) {
+
+ cuda_memcpy(cp_size * i, optr + i * cp_size, optr);
+ i = i * 2;
+ }
+
+ if (0 < repetitions - i)
+ cuda_memcpy(cp_size * (repetitions - i), optr + i * cp_size, optr);
+
+ return;
+ }
+#endif
+
+
#if 1
long tostr[D];
long tistr[D];
