Skip to content

Commit 79f9fe0

Browse files
authored
Adding the new operators available from the August OS update (#3)
## Summary Update the sample codes and utilities corresponding to the latest PICO OS update (5.14.0U) ## Details - [x] Readme updated: latest ROM version - [x] OpenXR header file updates, containing the latest ROM update - [x] Add the newly-added operators as pipeline methods: 1. SVD 1. Norm 1. HWC <-> CHW swaping
1 parent b1568e4 commit 79f9fe0

9 files changed

Lines changed: 5068 additions & 294 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ deploy your own algorithm packages.
8585

8686
#### (A) To run the demo, you will need
8787

88-
1. A PICO 4 Ultra device with the latest system update
88+
1. A PICO 4 Ultra device with the latest system update (OS version >= 5.14.0U)
8989
1. Android Studio, with Android NDK installed, suggested NDK version = 25
9090
1. Gradle and Android Gradle plugin (usually bundled with Android Studio install),
9191
suggested Gradle version = 8.7, Android Gradle Plugin version = 8.3.2

base/securemr_utils/pipeline.cpp

Lines changed: 63 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -382,20 +382,20 @@ Pipeline& Pipeline::uv2Cam(const std::shared_ptr<PipelineTensor>& uv, const std:
382382
const std::shared_ptr<PipelineTensor>& rightImg,
383383
const std::shared_ptr<PipelineTensor>& result) {
384384
// Check for null pointers
385-
CHECK_MSG(uv != nullptr, "uv2Cam uvPlaceholder1 is null");
386-
CHECK_MSG(timestamp != nullptr, "uv2Cam timestampPlaceholder1 is null");
387-
CHECK_MSG(cameraMatrix != nullptr, "uv2Cam cameraMatrixPlaceholder1 is null");
388-
CHECK_MSG(leftImg != nullptr, "uv2Cam leftImagePlaceholder is null");
389-
CHECK_MSG(rightImg != nullptr, "uv2Cam rightImagePlaceholder is null");
390-
CHECK_MSG(result != nullptr, "uv2Cam pointXYZ is null");
385+
CHECK_MSG(uv != nullptr, "uv2Cam uvPlaceholder1 is null")
386+
CHECK_MSG(timestamp != nullptr, "uv2Cam timestampPlaceholder1 is null")
387+
CHECK_MSG(cameraMatrix != nullptr, "uv2Cam cameraMatrixPlaceholder1 is null")
388+
CHECK_MSG(leftImg != nullptr, "uv2Cam leftImagePlaceholder is null")
389+
CHECK_MSG(rightImg != nullptr, "uv2Cam rightImagePlaceholder is null")
390+
CHECK_MSG(result != nullptr, "uv2Cam pointXYZ is null")
391391

392392
XrSecureMrOperatorPICO opHandle = XR_NULL_HANDLE;
393393
XrSecureMrOperatorUVTo3DPICO uvTo3DOperatorPico{XR_TYPE_SECURE_MR_OPERATOR_UV_TO_3D_PICO, nullptr};
394394
XrSecureMrOperatorCreateInfoPICO uvTo3DCreateInfoPico{
395395
XR_TYPE_SECURE_MR_OPERATOR_CREATE_INFO_PICO, nullptr,
396396
reinterpret_cast<XrSecureMrOperatorBaseHeaderPICO*>(&uvTo3DOperatorPico),
397397
XR_SECURE_MR_OPERATOR_TYPE_UV_TO_3D_IN_CAM_SPACE_PICO};
398-
CHECK_XRCMD(xrCreateSecureMrOperatorPICO(m_handle, &uvTo3DCreateInfoPico, &opHandle));
398+
CHECK_XRCMD(xrCreateSecureMrOperatorPICO(m_handle, &uvTo3DCreateInfoPico, &opHandle))
399399

400400
CHECK_XRCMD(xrSetSecureMrOperatorOperandByNamePICO(m_handle, opHandle, (XrSecureMrPipelineTensorPICO)*uv, "uv"))
401401
CHECK_XRCMD(
@@ -587,6 +587,62 @@ Pipeline& Pipeline::sortMatByColumn(const std::shared_ptr<PipelineTensor>& srcMa
587587
return *this;
588588
}
589589

590+
Pipeline& Pipeline::singularValueDecomposition(const std::shared_ptr<PipelineTensor>& src,
591+
const std::shared_ptr<PipelineTensor>& result_w,
592+
const std::shared_ptr<PipelineTensor>& result_u,
593+
const std::shared_ptr<PipelineTensor>& result_vt) {
594+
XrSecureMrOperatorPICO opHandle = XR_NULL_HANDLE;
595+
XrSecureMrOperatorCreateInfoPICO operatorCreateInfo{
596+
.type = XR_TYPE_SECURE_MR_OPERATOR_CREATE_INFO_PICO,
597+
.operatorType = XR_SECURE_MR_OPERATOR_TYPE_SVD_PICO,
598+
};
599+
CHECK_XRCMD(xrCreateSecureMrOperatorPICO(m_handle, &operatorCreateInfo, &opHandle))
600+
xrSetSecureMrOperatorOperandByNamePICO(m_handle, opHandle, static_cast<XrSecureMrPipelineTensorPICO>(*src), "src");
601+
if (result_w != nullptr) {
602+
xrSetSecureMrOperatorResultByNamePICO(m_handle, opHandle, static_cast<XrSecureMrPipelineTensorPICO>(*result_w),
603+
"w");
604+
}
605+
if (result_u != nullptr) {
606+
xrSetSecureMrOperatorResultByNamePICO(m_handle, opHandle, static_cast<XrSecureMrPipelineTensorPICO>(*result_u),
607+
"u");
608+
}
609+
if (result_vt != nullptr) {
610+
xrSetSecureMrOperatorResultByNamePICO(m_handle, opHandle, static_cast<XrSecureMrPipelineTensorPICO>(*result_vt),
611+
"vt");
612+
}
613+
return *this;
614+
}
615+
616+
Pipeline& Pipeline::norm(const std::shared_ptr<PipelineTensor>& src,
617+
const std::shared_ptr<PipelineTensor>& result_norm) {
618+
XrSecureMrOperatorPICO opHandle = XR_NULL_HANDLE;
619+
XrSecureMrOperatorCreateInfoPICO operatorCreateInfo{
620+
.type = XR_TYPE_SECURE_MR_OPERATOR_CREATE_INFO_PICO,
621+
.operatorType = XR_SECURE_MR_OPERATOR_TYPE_NORM_PICO,
622+
};
623+
CHECK_XRCMD(xrCreateSecureMrOperatorPICO(m_handle, &operatorCreateInfo, &opHandle))
624+
xrSetSecureMrOperatorOperandByNamePICO(m_handle, opHandle, static_cast<XrSecureMrPipelineTensorPICO>(*src),
625+
"operand0");
626+
xrSetSecureMrOperatorResultByNamePICO(m_handle, opHandle, static_cast<XrSecureMrPipelineTensorPICO>(*result_norm),
627+
"result0");
628+
return *this;
629+
}
630+
631+
Pipeline& Pipeline::convertHWC_CHW(const std::shared_ptr<PipelineTensor>& src,
632+
const std::shared_ptr<PipelineTensor>& result) {
633+
XrSecureMrOperatorPICO opHandle = XR_NULL_HANDLE;
634+
XrSecureMrOperatorCreateInfoPICO operatorCreateInfo{
635+
.type = XR_TYPE_SECURE_MR_OPERATOR_CREATE_INFO_PICO,
636+
.operatorType = XR_SECURE_MR_OPERATOR_TYPE_SWAP_HWC_CHW_PICO,
637+
};
638+
CHECK_XRCMD(xrCreateSecureMrOperatorPICO(m_handle, &operatorCreateInfo, &opHandle))
639+
xrSetSecureMrOperatorOperandByNamePICO(m_handle, opHandle, static_cast<XrSecureMrPipelineTensorPICO>(*src),
640+
"operand0");
641+
xrSetSecureMrOperatorResultByNamePICO(m_handle, opHandle, static_cast<XrSecureMrPipelineTensorPICO>(*result),
642+
"result0");
643+
return *this;
644+
}
645+
590646
Pipeline& Pipeline::inversion(const std::shared_ptr<PipelineTensor>& srcMat,
591647
const std::shared_ptr<PipelineTensor>& result_inverted) {
592648
XrSecureMrOperatorPICO opHandle = XR_NULL_HANDLE;

base/securemr_utils/pipeline.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,58 @@ class Pipeline final : public XrHandleAdapter<XrSecureMrPipelinePICO>, public st
430430
Pipeline& sortMatByColumn(const std::shared_ptr<PipelineTensor>& srcMat,
431431
const std::shared_ptr<PipelineTensor>& result_sortedMat,
432432
const std::shared_ptr<PipelineTensor>& result_indicesPerColumn);
433+
434+
/**
435+
*
436+
* Perform the singularity value decomposition (SVD) of a matrix
437+
*
438+
* @param src required, the matrix to be decomposed, must be a multi-dimensional tensor with 2 dimensions, therefore
439+
* usage flag <code>XR_SECURE_MR_TENSOR_TYPE_MAT_PICO</code> required銆?The shapes along the 2 dimensions
440+
* must be same, i.e., must be a square matrix.
441+
* @param result_w An optional result, the w result of the decomposition, usage flag
442+
* <code>XR_SECURE_MR_TENSOR_TYPE_MAT_PICO</code> required, and the tensor must have only two dimensions.
443+
* @param result_u An optional result, the u result of the decomposition, usage flag
444+
* <code>XR_SECURE_MR_TENSOR_TYPE_MAT_PICO</code> required, and the tensor must have only two dimensions.
445+
* @param result_vt An optional result, the vt result of the decomposition, usage flag
446+
* <code>XR_SECURE_MR_TENSOR_TYPE_MAT_PICO</code> required, and the tensor must have only two dimensions.
447+
* @return Reference to this pipeline
448+
*/
449+
Pipeline& singularValueDecomposition(const std::shared_ptr<PipelineTensor>& src,
450+
const std::shared_ptr<PipelineTensor>& result_w,
451+
const std::shared_ptr<PipelineTensor>& result_u,
452+
const std::shared_ptr<PipelineTensor>& result_vt);
453+
454+
/**
455+
* Compute the norm of a tensor (by default, L2 norm)
456+
*
457+
* @param src required, the tensor whose norm will be computed銆?It can be any tensor but the glTF tensor, i.e.,
458+
* the src tensor must not have <code>XR_SECURE_MR_TENSOR_TYPE_GLTF_PICO</code> usage flag.
459+
* @param result_norm required, the tensor to store the norm of <code>src</code>. It must be of only 1 channel, and
460+
* contains only one element. Hence, the tensor can only be: <ol>
461+
* <li>A scalar array tensor with usage flag <code>XR_SECURE_MR_TENSOR_TYPE_SCALAR_PICO</code>, of size 1, or</li>
462+
* <li>A scalar array tensor with usage flag <code>XR_SECURE_MR_TENSOR_TYPE_MAT_PICO</code>, with
463+
* dimensions = <code>(1, 1)</code></li>
464+
* </ol>
465+
* @return Reference to this pipeline
466+
*/
467+
Pipeline& norm(const std::shared_ptr<PipelineTensor>& src, const std::shared_ptr<PipelineTensor>& result_norm);
468+
469+
/**
470+
* Convert the HWC and CHW tensors. An HWC tensor is a 2-dimension tensor, with dimensions = <code>(H, W)</code> and
471+
* <code>C</code> channels. A CHW tensor is a 3-dimension tensor, with dimensions = <code>(C, H, W)</code> and
472+
* only 1 channel. If the input is an HWC tensor, the method converts it to a CHW one; otherwise, converting the
473+
* CHW input to HWC output.
474+
*
475+
* @param src required, the input tensor to be converted. Must either be a CHW or an HWC tensor, usage flag
476+
* <code>XR_SECURE_MR_TENSOR_TYPE_MAT_PICO</code> required, and number of dimensions must be either 2 or 3.
477+
* @param result required, the output of the conversion. If the <code>src</code> is a CHW tensor, the
478+
* <code>result</code> must be an HWC tensor. If the <code>src</code> is an HWC tensor, the <code>result</code> must
479+
* be a CHW tensor. usage flag <code>XR_SECURE_MR_TENSOR_TYPE_MAT_PICO</code> required, and number of dimensions must
480+
* be either 2 or 3. The last 2 dimensions of <code>result</code> must be the same as those of <code>src</code>
481+
* @return Reference to this pipeline
482+
*/
483+
Pipeline& convertHWC_CHW(const std::shared_ptr<PipelineTensor>& src, const std::shared_ptr<PipelineTensor>& result);
484+
433485
/**
434486
* Add to the pipeline an operator to conduct matrix inversion
435487
* Encapsulating operator of type <code>XR_SECURE_MR_OPERATOR_TYPE_INVERSION_PICO</code>

0 commit comments

Comments
 (0)