mirror of
				https://github.com/ggml-org/llama.cpp.git
				synced 2025-10-31 08:51:55 +00:00 
			
		
		
		
	vulkan : implement ggml_roll (ggml/1290)
ggml-ci
This commit is contained in:
		| @@ -432,6 +432,7 @@ struct vk_device_struct { | ||||
|     vk_pipeline pipeline_cos_f32; | ||||
|     vk_pipeline pipeline_clamp_f32; | ||||
|     vk_pipeline pipeline_pad_f32; | ||||
|     vk_pipeline pipeline_roll_f32; | ||||
|     vk_pipeline pipeline_repeat_f32, pipeline_repeat_back_f32; | ||||
|     vk_pipeline pipeline_cpy_f32_f32, pipeline_cpy_f32_f16, pipeline_cpy_f16_f16, pipeline_cpy_f16_f32, pipeline_cpy_f32_bf16; | ||||
|     vk_pipeline pipeline_contig_cpy_f32_f32, pipeline_contig_cpy_f32_f16, pipeline_contig_cpy_f16_f16, pipeline_contig_cpy_f16_f32, pipeline_contig_cpy_f32_bf16; | ||||
| @@ -694,6 +695,37 @@ struct vk_op_unary_push_constants { | ||||
| }; | ||||
| static_assert(sizeof(vk_op_unary_push_constants) <= 128, "sizeof(vk_op_unary_push_constants) must be <= 128"); | ||||
|  | ||||
| static vk_op_unary_push_constants vk_op_unary_push_constants_init(const ggml_tensor * src0, const ggml_tensor * dst, int64_t ne = 0) { | ||||
|     GGML_ASSERT(ne != 0 || (ggml_nelements(src0) == ggml_nelements(dst))); | ||||
|     ne = ne != 0 ? ne : ggml_nelements(dst); | ||||
|     GGML_ASSERT(ne <= (int64_t)std::numeric_limits<uint32_t>::max()); | ||||
|  | ||||
|     vk_op_unary_push_constants p{}; | ||||
|     p.ne = (uint32_t)ne; | ||||
|  | ||||
|     size_t src0_tsize = ggml_type_size(src0->type); | ||||
|     p.ne00 = (uint32_t)src0->ne[0]; | ||||
|     p.ne01 = (uint32_t)src0->ne[1]; | ||||
|     p.ne02 = (uint32_t)src0->ne[2]; | ||||
|     p.ne03 = (uint32_t)src0->ne[3]; | ||||
|     p.nb00 = (uint32_t)(src0->nb[0] / src0_tsize); | ||||
|     p.nb01 = (uint32_t)(src0->nb[1] / src0_tsize); | ||||
|     p.nb02 = (uint32_t)(src0->nb[2] / src0_tsize); | ||||
|     p.nb03 = (uint32_t)(src0->nb[3] / src0_tsize); | ||||
|  | ||||
|     size_t dst_tsize = ggml_type_size(dst->type); | ||||
|     p.ne10 = (uint32_t)dst->ne[0]; | ||||
|     p.ne11 = (uint32_t)dst->ne[1]; | ||||
|     p.ne12 = (uint32_t)dst->ne[2]; | ||||
|     p.ne13 = (uint32_t)dst->ne[3]; | ||||
|     p.nb10 = (uint32_t)(dst->nb[0] / dst_tsize); | ||||
|     p.nb11 = (uint32_t)(dst->nb[1] / dst_tsize); | ||||
|     p.nb12 = (uint32_t)(dst->nb[2] / dst_tsize); | ||||
|     p.nb13 = (uint32_t)(dst->nb[3] / dst_tsize); | ||||
|      | ||||
|     return p; // fastdiv values and offsets are initialized later in ggml_vk_op | ||||
| } | ||||
|  | ||||
| // See https://gmplib.org/~tege/divcnst-pldi94.pdf figure 4.1. | ||||
| // Precompute mp (m' in the paper) and L such that division | ||||
| // can be computed using a multiply (high 32b of 64b result) | ||||
| @@ -2836,6 +2868,8 @@ static void ggml_vk_load_shaders(vk_device& device) { | ||||
|  | ||||
|     ggml_vk_create_pipeline(device, device->pipeline_pad_f32, "pad_f32", pad_f32_len, pad_f32_data, "main", 2, sizeof(vk_op_unary_push_constants), {512, 1, 1}, {}, 1); | ||||
|  | ||||
|     ggml_vk_create_pipeline(device, device->pipeline_roll_f32, "roll_f32", roll_f32_len, roll_f32_data, "main", 2, sizeof(vk_op_unary_push_constants), {512, 1, 1}, {}, 1); | ||||
|  | ||||
|     ggml_vk_create_pipeline(device, device->pipeline_repeat_f32, "repeat_f32", repeat_f32_len, repeat_f32_data, "main", 2, sizeof(vk_op_unary_push_constants), {512, 1, 1}, {}, 1); | ||||
|     ggml_vk_create_pipeline(device, device->pipeline_repeat_back_f32, "repeat_back_f32", repeat_back_f32_len, repeat_back_f32_data, "main", 2, sizeof(vk_op_unary_push_constants), {512, 1, 1}, {}, 1); | ||||
|  | ||||
| @@ -6536,6 +6570,11 @@ static vk_pipeline ggml_vk_op_get_pipeline(ggml_backend_vk_context * ctx, const | ||||
|             return ctx->device->pipeline_pad_f32; | ||||
|         } | ||||
|         return nullptr; | ||||
|     case GGML_OP_ROLL: | ||||
|         if (src0->type == GGML_TYPE_F32 && dst->type == GGML_TYPE_F32) { | ||||
|             return ctx->device->pipeline_roll_f32; | ||||
|         } | ||||
|         return nullptr; | ||||
|     case GGML_OP_REPEAT: | ||||
|         if (ggml_type_size(src0->type) == sizeof(float) && ggml_type_size(dst->type) == sizeof(float)) { | ||||
|             return ctx->device->pipeline_repeat_f32; | ||||
| @@ -7085,6 +7124,7 @@ static void ggml_vk_op_f32(ggml_backend_vk_context * ctx, vk_context& subctx, co | ||||
|     case GGML_OP_COS: | ||||
|     case GGML_OP_CLAMP: | ||||
|     case GGML_OP_PAD: | ||||
|     case GGML_OP_ROLL: | ||||
|     case GGML_OP_REPEAT: | ||||
|     case GGML_OP_REPEAT_BACK: | ||||
|     case GGML_OP_CPY: | ||||
| @@ -7561,117 +7601,61 @@ static void ggml_vk_upscale(ggml_backend_vk_context * ctx, vk_context& subctx, c | ||||
| } | ||||
|  | ||||
| static void ggml_vk_scale(ggml_backend_vk_context * ctx, vk_context& subctx, const ggml_tensor * src0, ggml_tensor * dst, bool dryrun = false) { | ||||
|     float * op_params = (float *)dst->op_params; | ||||
|     const uint32_t src0_type_size = ggml_type_size(src0->type); | ||||
|     const uint32_t dst_type_size = ggml_type_size(dst->type); | ||||
|     vk_op_unary_push_constants p = vk_op_unary_push_constants_init(src0, dst); | ||||
|     p.param1 = ggml_get_op_params_f32(dst, 0); | ||||
|     p.param2 = ggml_get_op_params_f32(dst, 1); | ||||
|  | ||||
|     ggml_vk_op_f32<vk_op_unary_push_constants>(ctx, subctx, src0, nullptr, nullptr, dst, GGML_OP_SCALE, { | ||||
|         (uint32_t)ggml_nelements(src0), | ||||
|         (uint32_t)src0->ne[0], (uint32_t)src0->ne[1], (uint32_t)src0->ne[2], (uint32_t)src0->ne[3], (uint32_t)src0->nb[0] / src0_type_size, (uint32_t)src0->nb[1] / src0_type_size, (uint32_t)src0->nb[2] / src0_type_size, (uint32_t)src0->nb[3] / src0_type_size, | ||||
|         (uint32_t) dst->ne[0], (uint32_t) dst->ne[1], (uint32_t) dst->ne[2], (uint32_t) dst->ne[3], (uint32_t) dst->nb[0] /  dst_type_size, (uint32_t) dst->nb[1] /  dst_type_size, (uint32_t) dst->nb[2] /  dst_type_size, (uint32_t) dst->nb[3] /  dst_type_size, | ||||
|         0, | ||||
|         op_params[0], op_params[1], | ||||
|         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||||
|     }, dryrun); | ||||
|     ggml_vk_op_f32(ctx, subctx, src0, nullptr, nullptr, dst, GGML_OP_SCALE, std::move(p), dryrun); | ||||
| } | ||||
|  | ||||
| static void ggml_vk_sqr(ggml_backend_vk_context * ctx, vk_context& subctx, const ggml_tensor * src0, ggml_tensor * dst, bool dryrun = false) { | ||||
|     const uint32_t src0_type_size = ggml_type_size(src0->type); | ||||
|     const uint32_t dst_type_size = ggml_type_size(dst->type); | ||||
|  | ||||
|     ggml_vk_op_f32<vk_op_unary_push_constants>(ctx, subctx, src0, nullptr, nullptr, dst, GGML_OP_SQR, { | ||||
|         (uint32_t)ggml_nelements(src0), | ||||
|         (uint32_t)src0->ne[0], (uint32_t)src0->ne[1], (uint32_t)src0->ne[2], (uint32_t)src0->ne[3], (uint32_t)src0->nb[0] / src0_type_size, (uint32_t)src0->nb[1] / src0_type_size, (uint32_t)src0->nb[2] / src0_type_size, (uint32_t)src0->nb[3] / src0_type_size, | ||||
|         (uint32_t) dst->ne[0], (uint32_t) dst->ne[1], (uint32_t) dst->ne[2], (uint32_t) dst->ne[3], (uint32_t) dst->nb[0] /  dst_type_size, (uint32_t) dst->nb[1] /  dst_type_size, (uint32_t) dst->nb[2] /  dst_type_size, (uint32_t) dst->nb[3] /  dst_type_size, | ||||
|         0, | ||||
|         0.0f, 0.0f, | ||||
|         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||||
|     }, dryrun); | ||||
|     ggml_vk_op_f32(ctx, subctx, src0, nullptr, nullptr, dst, GGML_OP_SQR, vk_op_unary_push_constants_init(src0, dst), dryrun); | ||||
| } | ||||
|  | ||||
| static void ggml_vk_sin(ggml_backend_vk_context * ctx, vk_context& subctx, const ggml_tensor * src0, ggml_tensor * dst, bool dryrun = false) { | ||||
|     const uint32_t src0_type_size = ggml_type_size(src0->type); | ||||
|     const uint32_t dst_type_size = ggml_type_size(dst->type); | ||||
|  | ||||
|     ggml_vk_op_f32<vk_op_unary_push_constants>(ctx, subctx, src0, nullptr, nullptr, dst, GGML_OP_SIN, { | ||||
|         (uint32_t)ggml_nelements(src0), | ||||
|         (uint32_t)src0->ne[0], (uint32_t)src0->ne[1], (uint32_t)src0->ne[2], (uint32_t)src0->ne[3], (uint32_t)src0->nb[0] / src0_type_size, (uint32_t)src0->nb[1] / src0_type_size, (uint32_t)src0->nb[2] / src0_type_size, (uint32_t)src0->nb[3] / src0_type_size, | ||||
|         (uint32_t) dst->ne[0], (uint32_t) dst->ne[1], (uint32_t) dst->ne[2], (uint32_t) dst->ne[3], (uint32_t) dst->nb[0] /  dst_type_size, (uint32_t) dst->nb[1] /  dst_type_size, (uint32_t) dst->nb[2] /  dst_type_size, (uint32_t) dst->nb[3] /  dst_type_size, | ||||
|         0, | ||||
|         0.0f, 0.0f, | ||||
|         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||||
|     }, dryrun); | ||||
|     ggml_vk_op_f32(ctx, subctx, src0, nullptr, nullptr, dst, GGML_OP_SIN, vk_op_unary_push_constants_init(src0, dst), dryrun); | ||||
| } | ||||
|  | ||||
| static void ggml_vk_cos(ggml_backend_vk_context * ctx, vk_context& subctx, const ggml_tensor * src0, ggml_tensor * dst, bool dryrun = false) { | ||||
|     const uint32_t src0_type_size = ggml_type_size(src0->type); | ||||
|     const uint32_t dst_type_size = ggml_type_size(dst->type); | ||||
|  | ||||
|     ggml_vk_op_f32<vk_op_unary_push_constants>(ctx, subctx, src0, nullptr, nullptr, dst, GGML_OP_COS, { | ||||
|         (uint32_t)ggml_nelements(src0), | ||||
|         (uint32_t)src0->ne[0], (uint32_t)src0->ne[1], (uint32_t)src0->ne[2], (uint32_t)src0->ne[3], (uint32_t)src0->nb[0] / src0_type_size, (uint32_t)src0->nb[1] / src0_type_size, (uint32_t)src0->nb[2] / src0_type_size, (uint32_t)src0->nb[3] / src0_type_size, | ||||
|         (uint32_t) dst->ne[0], (uint32_t) dst->ne[1], (uint32_t) dst->ne[2], (uint32_t) dst->ne[3], (uint32_t) dst->nb[0] /  dst_type_size, (uint32_t) dst->nb[1] /  dst_type_size, (uint32_t) dst->nb[2] /  dst_type_size, (uint32_t) dst->nb[3] /  dst_type_size, | ||||
|         0, | ||||
|         0.0f, 0.0f, | ||||
|         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||||
|     }, dryrun); | ||||
|     ggml_vk_op_f32(ctx, subctx, src0, nullptr, nullptr, dst, GGML_OP_COS, vk_op_unary_push_constants_init(src0, dst), dryrun); | ||||
| } | ||||
|  | ||||
| static void ggml_vk_clamp(ggml_backend_vk_context * ctx, vk_context& subctx, const ggml_tensor * src0, ggml_tensor * dst, bool dryrun = false) { | ||||
|     float * op_params = (float *)dst->op_params; | ||||
|     const uint32_t src0_type_size = ggml_type_size(src0->type); | ||||
|     const uint32_t dst_type_size = ggml_type_size(dst->type); | ||||
|     vk_op_unary_push_constants p = vk_op_unary_push_constants_init(src0, dst); | ||||
|     p.param1 = ggml_get_op_params_f32(dst, 0); | ||||
|     p.param2 = ggml_get_op_params_f32(dst, 1); | ||||
|  | ||||
|     ggml_vk_op_f32<vk_op_unary_push_constants>(ctx, subctx, src0, nullptr, nullptr, dst, GGML_OP_CLAMP, { | ||||
|         (uint32_t)ggml_nelements(src0), | ||||
|         (uint32_t)src0->ne[0], (uint32_t)src0->ne[1], (uint32_t)src0->ne[2], (uint32_t)src0->ne[3], (uint32_t)src0->nb[0] / src0_type_size, (uint32_t)src0->nb[1] / src0_type_size, (uint32_t)src0->nb[2] / src0_type_size, (uint32_t)src0->nb[3] / src0_type_size, | ||||
|         (uint32_t) dst->ne[0], (uint32_t) dst->ne[1], (uint32_t) dst->ne[2], (uint32_t) dst->ne[3], (uint32_t) dst->nb[0] /  dst_type_size, (uint32_t) dst->nb[1] /  dst_type_size, (uint32_t) dst->nb[2] /  dst_type_size, (uint32_t) dst->nb[3] /  dst_type_size, | ||||
|         0, | ||||
|         op_params[0], op_params[1], | ||||
|         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||||
|     }, dryrun); | ||||
|     ggml_vk_op_f32(ctx, subctx, src0, nullptr, nullptr, dst, GGML_OP_CLAMP, std::move(p), dryrun); | ||||
| } | ||||
|  | ||||
| static void ggml_vk_pad(ggml_backend_vk_context * ctx, vk_context& subctx, const ggml_tensor * src0, ggml_tensor * dst, bool dryrun = false) { | ||||
|     const uint32_t src0_type_size = ggml_type_size(src0->type); | ||||
|     const uint32_t dst_type_size = ggml_type_size(dst->type); | ||||
|     vk_op_unary_push_constants p = vk_op_unary_push_constants_init(src0, dst, ggml_nelements(dst)); | ||||
|     ggml_vk_op_f32(ctx, subctx, src0, nullptr, nullptr, dst, GGML_OP_PAD, std::move(p), dryrun); | ||||
| } | ||||
|  | ||||
|     ggml_vk_op_f32<vk_op_unary_push_constants>(ctx, subctx, src0, nullptr, nullptr, dst, GGML_OP_PAD, { | ||||
|         (uint32_t)ggml_nelements(dst), | ||||
|         (uint32_t)src0->ne[0], (uint32_t)src0->ne[1], (uint32_t)src0->ne[2], (uint32_t)src0->ne[3], (uint32_t)src0->nb[0] / src0_type_size, (uint32_t)src0->nb[1] / src0_type_size, (uint32_t)src0->nb[2] / src0_type_size, (uint32_t)src0->nb[3] / src0_type_size, | ||||
|         (uint32_t) dst->ne[0], (uint32_t) dst->ne[1], (uint32_t) dst->ne[2], (uint32_t) dst->ne[3], (uint32_t) dst->nb[0] /  dst_type_size, (uint32_t) dst->nb[1] /  dst_type_size, (uint32_t) dst->nb[2] /  dst_type_size, (uint32_t) dst->nb[3] /  dst_type_size, | ||||
|         0, | ||||
|         0.0f, 0.0f, | ||||
|         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||||
|     }, dryrun); | ||||
| static void ggml_vk_roll(ggml_backend_vk_context * ctx, vk_context& subctx, const ggml_tensor * src0, ggml_tensor * dst, bool dryrun = false) { | ||||
|     const int32_t s0 = ggml_get_op_params_i32(dst, 0); | ||||
|     const int32_t s1 = ggml_get_op_params_i32(dst, 1); | ||||
|     const int32_t s2 = ggml_get_op_params_i32(dst, 2); | ||||
|     const int32_t s3 = ggml_get_op_params_i32(dst, 3); | ||||
|     const uint32_t s01_packed = ((s0 + 0x8000) << 16) | (s1 + 0x8000); | ||||
|     const uint32_t s23_packed = ((s2 + 0x8000) << 16) | (s3 + 0x8000); | ||||
|  | ||||
|     vk_op_unary_push_constants p = vk_op_unary_push_constants_init(src0, dst); | ||||
|     memcpy(&p.param1, &s01_packed, sizeof(float)); | ||||
|     memcpy(&p.param2, &s23_packed, sizeof(float)); | ||||
|  | ||||
|     ggml_vk_op_f32(ctx, subctx, src0, nullptr, nullptr, dst, GGML_OP_ROLL, std::move(p), dryrun); | ||||
| } | ||||
|  | ||||
| static void ggml_vk_repeat(ggml_backend_vk_context * ctx, vk_context& subctx, const ggml_tensor * src0, ggml_tensor * dst, bool dryrun = false) { | ||||
|     const uint32_t src0_type_size = ggml_type_size(src0->type); | ||||
|     const uint32_t dst_type_size = ggml_type_size(dst->type); | ||||
|  | ||||
|     ggml_vk_op_f32<vk_op_unary_push_constants>(ctx, subctx, src0, nullptr, nullptr, dst, GGML_OP_REPEAT, { | ||||
|         (uint32_t)ggml_nelements(dst), | ||||
|         (uint32_t)src0->ne[0], (uint32_t)src0->ne[1], (uint32_t)src0->ne[2], (uint32_t)src0->ne[3], (uint32_t)src0->nb[0] / src0_type_size, (uint32_t)src0->nb[1] / src0_type_size, (uint32_t)src0->nb[2] / src0_type_size, (uint32_t)src0->nb[3] / src0_type_size, | ||||
|         (uint32_t) dst->ne[0], (uint32_t) dst->ne[1], (uint32_t) dst->ne[2], (uint32_t) dst->ne[3], (uint32_t) dst->nb[0] /  dst_type_size, (uint32_t) dst->nb[1] /  dst_type_size, (uint32_t) dst->nb[2] /  dst_type_size, (uint32_t) dst->nb[3] /  dst_type_size, | ||||
|         0, | ||||
|         0.0f, 0.0f, | ||||
|         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||||
|     }, dryrun); | ||||
|     vk_op_unary_push_constants p = vk_op_unary_push_constants_init(src0, dst, ggml_nelements(dst)); | ||||
|     ggml_vk_op_f32(ctx, subctx, src0, nullptr, nullptr, dst, GGML_OP_REPEAT, std::move(p), dryrun); | ||||
| } | ||||
|  | ||||
| static void ggml_vk_repeat_back(ggml_backend_vk_context * ctx, vk_context& subctx, const ggml_tensor * src0, ggml_tensor * dst, bool dryrun = false) { | ||||
|     const uint32_t src0_type_size = ggml_type_size(src0->type); | ||||
|     const uint32_t dst_type_size = ggml_type_size(dst->type); | ||||
|  | ||||
|     ggml_vk_op_f32<vk_op_unary_push_constants>(ctx, subctx, src0, nullptr, nullptr, dst, GGML_OP_REPEAT_BACK, { | ||||
|         (uint32_t)ggml_nelements(dst), | ||||
|         (uint32_t)src0->ne[0], (uint32_t)src0->ne[1], (uint32_t)src0->ne[2], (uint32_t)src0->ne[3], (uint32_t)src0->nb[0] / src0_type_size, (uint32_t)src0->nb[1] / src0_type_size, (uint32_t)src0->nb[2] / src0_type_size, (uint32_t)src0->nb[3] / src0_type_size, | ||||
|         (uint32_t) dst->ne[0], (uint32_t) dst->ne[1], (uint32_t) dst->ne[2], (uint32_t) dst->ne[3], (uint32_t) dst->nb[0] /  dst_type_size, (uint32_t) dst->nb[1] /  dst_type_size, (uint32_t) dst->nb[2] /  dst_type_size, (uint32_t) dst->nb[3] /  dst_type_size, | ||||
|         0, | ||||
|         0.0f, 0.0f, | ||||
|         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||||
|     }, dryrun); | ||||
|     vk_op_unary_push_constants p = vk_op_unary_push_constants_init(src0, dst, ggml_nelements(dst)); | ||||
|     ggml_vk_op_f32(ctx, subctx, src0, nullptr, nullptr, dst, GGML_OP_REPEAT_BACK, std::move(p), dryrun); | ||||
| } | ||||
|  | ||||
| static void ggml_vk_cpy(ggml_backend_vk_context * ctx, vk_context& subctx, const ggml_tensor * src0, ggml_tensor * dst, bool dryrun = false) { | ||||
| @@ -7689,14 +7673,8 @@ static void ggml_vk_cpy(ggml_backend_vk_context * ctx, vk_context& subctx, const | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     ggml_vk_op_f32<vk_op_unary_push_constants>(ctx, subctx, src0, nullptr, nullptr, dst, GGML_OP_CPY, { | ||||
|         ne, | ||||
|         (uint32_t)src0->ne[0], (uint32_t)src0->ne[1], (uint32_t)src0->ne[2], (uint32_t)src0->ne[3], (uint32_t)src0->nb[0] / src0_type_size, (uint32_t)src0->nb[1] / src0_type_size, (uint32_t)src0->nb[2] / src0_type_size, (uint32_t)src0->nb[3] / src0_type_size, | ||||
|         (uint32_t) dst->ne[0], (uint32_t) dst->ne[1], (uint32_t) dst->ne[2], (uint32_t) dst->ne[3], (uint32_t) dst->nb[0] /  dst_type_size, (uint32_t) dst->nb[1] /  dst_type_size, (uint32_t) dst->nb[2] /  dst_type_size, (uint32_t) dst->nb[3] /  dst_type_size, | ||||
|         0, | ||||
|         0.0f, 0.0f, | ||||
|         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||||
|     }, dryrun); | ||||
|     vk_op_unary_push_constants p = vk_op_unary_push_constants_init(src0, dst, ne); | ||||
|     ggml_vk_op_f32(ctx, subctx, src0, nullptr, nullptr, dst, GGML_OP_CPY, std::move(p), dryrun); | ||||
| } | ||||
|  | ||||
| static void ggml_vk_set_rows(ggml_backend_vk_context * ctx, vk_context& subctx, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst, bool dryrun = false) { | ||||
| @@ -9033,6 +9011,7 @@ static bool ggml_vk_build_graph(ggml_backend_vk_context * ctx, ggml_cgraph * cgr | ||||
|     case GGML_OP_COS: | ||||
|     case GGML_OP_CLAMP: | ||||
|     case GGML_OP_PAD: | ||||
|     case GGML_OP_ROLL: | ||||
|     case GGML_OP_CPY: | ||||
|     case GGML_OP_SET_ROWS: | ||||
|     case GGML_OP_CONT: | ||||
| @@ -9204,6 +9183,10 @@ static bool ggml_vk_build_graph(ggml_backend_vk_context * ctx, ggml_cgraph * cgr | ||||
|     case GGML_OP_PAD: | ||||
|         ggml_vk_pad(ctx, compute_ctx, src0, node, dryrun); | ||||
|  | ||||
|         break; | ||||
|     case GGML_OP_ROLL: | ||||
|         ggml_vk_roll(ctx, compute_ctx, src0, node, dryrun); | ||||
|  | ||||
|         break; | ||||
|     case GGML_OP_CPY: | ||||
|     case GGML_OP_CONT: | ||||
| @@ -9428,6 +9411,7 @@ static bool ggml_vk_compute_forward(ggml_backend_vk_context * ctx, ggml_cgraph * | ||||
|     case GGML_OP_COS: | ||||
|     case GGML_OP_CLAMP: | ||||
|     case GGML_OP_PAD: | ||||
|     case GGML_OP_ROLL: | ||||
|     case GGML_OP_CPY: | ||||
|     case GGML_OP_SET_ROWS: | ||||
|     case GGML_OP_CONT: | ||||
|   | ||||
							
								
								
									
										46
									
								
								ggml/src/ggml-vulkan/vulkan-shaders/roll.comp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								ggml/src/ggml-vulkan/vulkan-shaders/roll.comp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| #version 450 | ||||
|  | ||||
| #include "types.comp" | ||||
| #include "generic_unary_head.comp" | ||||
|  | ||||
| layout(local_size_x = 512, local_size_y = 1, local_size_z = 1) in; | ||||
|  | ||||
| uint wrap_idx(int i, uint ne) { | ||||
|     if (i < 0) { | ||||
|         return i + ne; | ||||
|     } else if (i >= ne) { | ||||
|         return i - ne; | ||||
|     } | ||||
|     return i; | ||||
| } | ||||
|  | ||||
| void main() { | ||||
|     const uint idx = get_idx(); | ||||
|     if (idx >= p.ne) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     const uint i3 = fastdiv(idx, p.ne1_012mp, p.ne1_012L); | ||||
|     const uint i3_offset = i3 * p.ne12*p.ne11*p.ne10; | ||||
|     const uint i2 = fastdiv(idx - i3_offset, p.ne1_01mp, p.ne1_01L); | ||||
|     const uint i2_offset = i2*p.ne11*p.ne10; | ||||
|     const uint i1 = fastdiv(idx - i3_offset - i2_offset, p.ne1_0mp, p.ne1_0L); | ||||
|     const uint i0 = idx - i3_offset - i2_offset - i1*p.ne10; | ||||
|  | ||||
|     const uint p1 = floatBitsToUint(p.param1); | ||||
|     const uint p2 = floatBitsToUint(p.param2); | ||||
|     const int s0 = int(p1 >> 16)    - 0x8000; | ||||
|     const int s1 = int(p1 & 0xFFFF) - 0x8000; | ||||
|     const int s2 = int(p2 >> 16)    - 0x8000; | ||||
|     const int s3 = int(p2 & 0xFFFF) - 0x8000; | ||||
|  | ||||
|     const uint i00 = wrap_idx(int(i0) - s0, p.ne10); | ||||
|     const uint i01 = wrap_idx(int(i1) - s1, p.ne11); | ||||
|     const uint i02 = wrap_idx(int(i2) - s2, p.ne12); | ||||
|     const uint i03 = wrap_idx(int(i3) - s3, p.ne13); | ||||
|  | ||||
|     const uint a_idx = i03*p.nb03 + i02*p.nb02 + i01*p.nb01 + i00*p.nb00; | ||||
|     const uint d_idx = i3 *p.nb13 + i2 *p.nb12 + i1 *p.nb11 + i0 *p.nb10; | ||||
|  | ||||
|     data_d[get_doffset() + d_idx] = D_TYPE(data_a[get_aoffset() + a_idx]); | ||||
| } | ||||
| @@ -653,6 +653,8 @@ void process_shaders() { | ||||
|     string_to_spv("conv2d_dw_whcn_f32", "conv2d_dw.comp", merge_maps(base_dict, {{"A_TYPE", "float"}, {"B_TYPE", "float"}, {"D_TYPE", "float"}, {"WHCN", "1"}})); | ||||
|     string_to_spv("conv2d_dw_cwhn_f32", "conv2d_dw.comp", merge_maps(base_dict, {{"A_TYPE", "float"}, {"B_TYPE", "float"}, {"D_TYPE", "float"}, {"CWHN", "1"}})); | ||||
|  | ||||
|     string_to_spv("roll_f32", "roll.comp", merge_maps(base_dict, {{"A_TYPE", "float"}, {"D_TYPE", "float"}})); | ||||
|  | ||||
|     for (auto &c : compiles) { | ||||
|         c.wait(); | ||||
|     } | ||||
|   | ||||
| @@ -4114,6 +4114,32 @@ struct test_pad_reflect_1d : public test_case { | ||||
|     } | ||||
| }; | ||||
|  | ||||
| // GGML_OP_ROLL | ||||
| struct test_roll : public test_case { | ||||
|     const int shift0; | ||||
|     const int shift1; | ||||
|     const int shift3; | ||||
|     const int shift4; | ||||
|  | ||||
|     std::string vars() override { | ||||
|         return VARS_TO_STR4(shift0, shift1, shift3, shift4); | ||||
|     } | ||||
|  | ||||
|     test_roll(int shift0 = 3, int shift1 = -2, int shift3 = 1, int shift4 = -1) | ||||
|         : shift0(shift0), shift1(shift1), shift3(shift3), shift4(shift4) {} | ||||
|  | ||||
|     ggml_tensor * build_graph(ggml_context * ctx) override { | ||||
|         int64_t ne[4] = {10, 5, 4, 3}; | ||||
|         ggml_tensor * a = ggml_new_tensor(ctx, GGML_TYPE_F32, 4, ne); | ||||
|         ggml_set_name(a, "a"); | ||||
|  | ||||
|         ggml_tensor * out = ggml_roll(ctx, a, shift0, shift1, shift3, shift4); | ||||
|         ggml_set_name(out, "out"); | ||||
|  | ||||
|         return out; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| // GGML_OP_ARANGE | ||||
| struct test_arange : public test_case { | ||||
|     const ggml_type type; | ||||
| @@ -5484,6 +5510,7 @@ static std::vector<std::unique_ptr<test_case>> make_test_cases_eval() { | ||||
|     test_cases.emplace_back(new test_acc()); | ||||
|     test_cases.emplace_back(new test_pad()); | ||||
|     test_cases.emplace_back(new test_pad_reflect_1d()); | ||||
|     test_cases.emplace_back(new test_roll()); | ||||
|     test_cases.emplace_back(new test_arange()); | ||||
|     test_cases.emplace_back(new test_timestep_embedding()); | ||||
|     test_cases.emplace_back(new test_leaky_relu()); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Acly
					Acly