-
Notifications
You must be signed in to change notification settings - Fork 151
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
Validation Error :VUID-vkBeginCommandBuffer-commandBuffer-00050 #296
Comments
@cracy3m thank you very much for reporting this. At first glance this does seem to work as intended, you can see the test If indeed this is not different size then it may be a bug, is this basically running the example in the demo? What is the version of your vulkan driver and headers? If it is indeed a bug we'll be keen to fix it. For the time being you could use the workaround as show in the tests under TEST(TestPushConstants, TestConstantsAlgoDispatchOverride)
{
{
std::string shader(R"(
#version 450
layout(push_constant) uniform PushConstants {
float x;
float y;
float z;
} pcs;
layout (local_size_x = 1) in;
layout(set = 0, binding = 0) buffer a { float pa[]; };
void main() {
pa[0] += pcs.x;
pa[1] += pcs.y;
pa[2] += pcs.z;
})");
std::vector<uint32_t> spirv = compileSource(shader);
std::shared_ptr<kp::Sequence> sq = nullptr;
{
kp::Manager mgr;
std::shared_ptr<kp::TensorT<float>> tensor =
mgr.tensor({ 0, 0, 0 });
std::shared_ptr<kp::Algorithm> algo = mgr.algorithm(
{ tensor }, spirv, kp::Workgroup({ 1 }), {}, { 0.0, 0.0, 0.0 });
sq = mgr.sequence()->eval<kp::OpTensorSyncDevice>({ tensor });
// We need to run this in sequence to avoid race condition
// We can't use atomicAdd as swiftshader doesn't support it for
// float
sq->eval<kp::OpAlgoDispatch>(algo,
std::vector<float>{ 0.1, 0.2, 0.3 });
sq->eval<kp::OpAlgoDispatch>(algo,
std::vector<float>{ 0.3, 0.2, 0.1 });
sq->eval<kp::OpTensorSyncLocal>({ tensor });
EXPECT_EQ(tensor->vector(), std::vector<float>({ 0.4, 0.4, 0.4 }));
}
}
} |
My test context: My test code: void kompute(const std::string& shader) {
// 1. Create Kompute Manager with default settings (device 0, first queue and no extensions)
kp::Manager mgr;
// 2. Create and initialise Kompute Tensors through manager
// Default tensor constructor simplifies creation of float values
auto tensorInA = mgr.tensor({ 2., 2., 2. });
auto tensorInB = mgr.tensor({ 1., 2., 3. });
// Explicit type constructor supports uint32, int32, double, float and bool
auto tensorOutA = mgr.tensorT<uint32_t>({ 0, 0, 0 });
auto tensorOutB = mgr.tensorT<uint32_t>({ 0, 0, 0 });
std::vector<std::shared_ptr<kp::Tensor>> params = {tensorInA, tensorInB, tensorOutA, tensorOutB};
// 3. Create algorithm based on shader (supports buffers & push/spec constants)
kp::Workgroup workgroup{3, 1, 1}; // c++11 std::array 不能用括号加{}初始化
std::vector<float> specConsts({ 2 });
std::vector<float> pushConstsA({ 2.0 });
std::vector<float> pushConstsB({ 3.0 });
std::vector<uint32_t> orgspirv = compileSource(shader);
// std::vector<uint32_t> tspriv;
// tspriv.insert(tspriv.begin(),
// reinterpret_cast<const uint32_t *>(spirv_demo),
// reinterpret_cast<const uint32_t *>(spirv_demo + sizeof (spirv_demo)) + 1
// );
std::vector<uint32_t> tspriv(spirv_demo,
spirv_demo + sizeof (spirv_demo) / sizeof (spirv_demo[0]) //sizeof (decltype(spirv_demo[0]))
);
// std::vector<uint32_t> tspriv(ExtendAndWin,
// ExtendAndWin + sizeof (ExtendAndWin) / sizeof (ExtendAndWin[0]) //sizeof (decltype(spirv_demo[0]))
// );
KP_LOG_INFO("is compiled equel to showed : {}", orgspirv == tspriv);
auto algorithm = mgr.algorithm(params,
// See documentation shader section for compileSource
tspriv, //compileSource(shader),
workgroup,
specConsts,
pushConstsA);
// 4. Run operation synchronously using sequence
mgr.sequence()
->record<kp::OpTensorSyncDevice>(params)
->record<kp::OpAlgoDispatch>(algorithm) // Binds default push consts
->eval() // Evaluates the two recorded operations
->record<kp::OpAlgoDispatch>(algorithm, pushConstsB) // Overrides push consts
->eval(); // Evaluates only last recorded operation
// 5. Sync results from the GPU asynchronously
auto sq = mgr.sequence();
sq->evalAsync<kp::OpTensorSyncLocal>(params);
// ... Do other work asynchronously whilst GPU finishes
sq->evalAwait();
// fmt::print("{0:*^{1}}\n","result",30);
KP_LOG_INFO("{0:*^{1}}","result",30);
KP_LOG_INFO(fmt::format("tensorOutA: {}", fmt::join(tensorOutA->vector(), ", ")));
KP_LOG_INFO(fmt::format("tensorOutB: {}", fmt::join(tensorOutB->vector(), ", ")));
// // Prints the first output which is: { 4, 8, 12 }
// for (const float& elem : tensorOutA->vector()) std::cout << elem << " ";
// std::cout << std::endl;
// // Prints the second output which is: { 10, 10, 10 }
// for (const float& elem : tensorOutB->vector()) std::cout << elem << " ";
// std::cout << std::endl;
} // Manages / releases all CPU and GPU memory resources
int main()
{
// kpextSetLogger("kpextLogger", 1, 2);
// kpextSetLogger(nullptr, 1, 2);
#ifdef DEBUG
spdlog::set_level(spdlog::level::debug);
SPDLOG_LOGGER_DEBUG(spdlog::default_logger_raw(), "spdlog::default_logger_raw");
spdlog::set_level(spdlog::level::info);
KP_LOG_DEBUG("this debug log will not show \n");
KP_LOG_INFO("this info log will show","\n");
#endif
// spdlog::set_level(spdlog::level::off);
spdlog::set_level(spdlog::level::debug);
// Define a raw string shader (or use the Kompute tools to compile to SPIRV / C++ header
// files). This shader shows some of the main components including constants, buffers, etc
std::string shader = (R"(
#version 450
layout (local_size_x = 1) in;
// The input tensors bind index is relative to index in parameter passed
layout(set = 0, binding = 0) buffer buf_in_a { float in_a[]; };
layout(set = 0, binding = 1) buffer buf_in_b { float in_b[]; };
layout(set = 0, binding = 2) buffer buf_out_a { uint out_a[]; };
layout(set = 0, binding = 3) buffer buf_out_b { uint out_b[]; };
// Kompute supports push constants updated on dispatch
layout(push_constant) uniform PushConstants {
float val;
} push_const;
// Kompute also supports spec constants on initalization
layout(constant_id = 0) const float const_one = 0;
void main() {
uint index = gl_GlobalInvocationID.x;
out_a[index] += uint( in_a[index] * in_b[index] );
out_b[index] += uint( const_one * push_const.val );
}
)");
kompute(shader);
return 0;
}
Log info:
|
I test void test(){
{
std::string shader(R"(
#version 450
layout(push_constant) uniform PushConstants {
float x;
float y;
float z;
} pcs;
layout (local_size_x = 1) in;
layout(set = 0, binding = 0) buffer a { float pa[]; };
void main() {
pa[0] += pcs.x;
pa[1] += pcs.y;
pa[2] += pcs.z;
})");
std::vector<uint32_t> spirv = compileSource(shader);
std::shared_ptr<kp::Sequence> sq = nullptr;
{
kp::Manager mgr;
std::shared_ptr<kp::TensorT<float>> tensor =
mgr.tensor({ 0, 0, 0 });
std::shared_ptr<kp::Algorithm> algo = mgr.algorithm(
{ tensor }, spirv, kp::Workgroup({ 1 }), {}, { 0.0, 0.0, 0.0 });
sq = mgr.sequence()->eval<kp::OpTensorSyncDevice>({ tensor });
// We need to run this in sequence to avoid race condition
// We can't use atomicAdd as swiftshader doesn't support it for
// float
sq->eval<kp::OpAlgoDispatch>(algo,
std::vector<float>{ 0.1f, 0.2f, 0.3f }); //VUID-vkBeginCommandBuffer-commandBuffer-00050
sq->eval<kp::OpAlgoDispatch>(algo,
std::vector<float>{ 0.3f, 0.2f, 0.1f }); //VUID-vkBeginCommandBuffer-commandBuffer-00050
sq->eval<kp::OpTensorSyncLocal>({ tensor }); //VUID-vkBeginCommandBuffer-commandBuffer-00050
// EXPECT_EQ(tensor->vector(), std::vector<float>({ 0.4, 0.4, 0.4 }));
}
}
}
int main()
{
// kpextSetLogger("kpextLogger", 1, 2);
// kpextSetLogger(nullptr, 1, 2);
#ifdef DEBUG
spdlog::set_level(spdlog::level::debug);
SPDLOG_LOGGER_DEBUG(spdlog::default_logger_raw(), "spdlog::default_logger_raw");
spdlog::set_level(spdlog::level::info);
KP_LOG_DEBUG("this debug log will not show \n");
KP_LOG_INFO("this info log will show","\n");
#endif
// spdlog::set_level(spdlog::level::off);
spdlog::set_level(spdlog::level::debug);
test();
... Invoke stack:
Log :
|
Ok I see, it seems it's a validation error from the validation pipelines, I see what you mean now. Let me try to replicate and I can confirm the results. |
@axsaucedo Thanks, I think use |
Fixed via #392 |
Calling record() after calling eval() on the same kp:: sequence object will cause a vuid-vkbegincommandbuffer-commandbuffer-00050 Vulkan validation error.
Error occur in README.md demo:
Kompute create vulkan command pool without VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, but kp::Sequence::begin will call vkBeginCommandBuffer(if command buffer is not in the initial state, the validation layer will get a error message ),
Will such error cause problems? Or should record() not be used after kp:: sequence:: eval()?
The text was updated successfully, but these errors were encountered: