/home/runner/work/HiCR/HiCR/include/hicr/backends/nosv/processingUnit.hpp Source File

HiCR: /home/runner/work/HiCR/HiCR/include/hicr/backends/nosv/processingUnit.hpp Source File
HiCR
processingUnit.hpp
Go to the documentation of this file.
1/*
2 * Copyright 2025 Huawei Technologies Co., Ltd.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
23#pragma once
24
25#include <memory>
26#include <utility>
27#include <nosv.h>
28#include <nosv/affinity.h>
29#include <hicr/core/definitions.hpp>
32
35
36namespace HiCR::backend::nosv
37{
38
42class ComputeManager;
43
53{
55
56 public:
57
63 __INLINE__ ProcessingUnit(const std::shared_ptr<HiCR::ComputeResource> &computeResource)
64 : HiCR::ProcessingUnit(computeResource)
65 {
66 // Getting up-casted pointer for the processing unit
67 auto c = dynamic_pointer_cast<HiCR::backend::hwloc::ComputeResource>(computeResource);
68
69 // Checking whether the execution unit passed is compatible with this backend
70 if (c == nullptr) HICR_THROW_LOGIC("The passed compute resource is not supported by this processing unit type\n");
71
72 // Getting the logical processor ID of the compute resource
73 auto pid = c->getProcessorId();
74
75 // setting up the nosv affinity for the execution task
76 _nosv_affinity = nosv_affinity_get(pid, NOSV_AFFINITY_LEVEL_CPU, NOSV_AFFINITY_TYPE_STRICT);
77 };
78
84 [[nodiscard]] __INLINE__ std::string getType() override { return "nOS-V worker thread"; }
85
86 private:
87
91 __INLINE__ void initialize()
92 {
93 // Nothing to do here
94 }
95
99 __INLINE__ void suspend() { HICR_THROW_RUNTIME("nOS-V can't suspend a worker thread.\n"); }
100
104 __INLINE__ void resume() { HICR_THROW_RUNTIME("nOS-V can't resume a worker thread.\n"); }
105
109 __INLINE__ void start(std::unique_ptr<HiCR::ExecutionState> &executionState)
110 {
111 // Getting up-casted pointer of the execution state
112 auto c = std::unique_ptr<HiCR::backend::nosv::ExecutionState>(dynamic_cast<HiCR::backend::nosv::ExecutionState *>(executionState.get()));
113
114 // Checking whether the execution state passed is compatible with this backend
115 if (c == nullptr) HICR_THROW_LOGIC("The passed execution state is not supported by this processing unit type\n");
116
117 // Prevent double deletion since c now owns the pointer
118 executionState.release();
119
120 // Move the ovnership of the execution state to this instance
121 _executionState = std::move(c);
122
123 // Set execution state task metadata for this PU
124 auto metadata = (ExecutionState::taskMetadata_t *)getTaskMetadata(_executionState->_executionStateTask);
125 metadata->mainLoop = true;
126
127 // Initialize the barrier
128 check(nosv_barrier_init(&(metadata->mainLoop_barrier), NOSV_BARRIER_NONE, 2));
129
130 // Set the task affinity
131 nosv_set_task_affinity(_executionState->_executionStateTask, &_nosv_affinity);
132
133 // Submit the job (Now, nosv will put it inside a queue and runs it ASAP)
134 check(nosv_submit(_executionState->_executionStateTask, NOSV_SUBMIT_NONE));
135
136 // Barrier to as we have to wait until the execution state task is properly initialized and running
137 check(nosv_barrier_wait(metadata->mainLoop_barrier));
138
139 // Destroying the barrier as it is no longer needed
140 check(nosv_barrier_destroy(metadata->mainLoop_barrier));
141 }
142
146 __INLINE__ void terminate()
147 {
148 // Nothing to do here. Just wait for the nOS-V worker thread to finalize on its own.
149 }
150
154 __INLINE__ void await()
155 {
156 // Get the execution state metadata
157 auto metadata = (ExecutionState::taskMetadata_t *)getTaskMetadata(_executionState->_executionStateTask);
158
159 // Assertion to check that only the PU task is getting to this
160 if (metadata->mainLoop == false) HICR_THROW_RUNTIME("Abort, only PU from the worker mainLoop should get here.\n");
161
162 // Busy wait until the function call fully executed (i.e. the worker mainLoop finished)
163 while (_executionState->checkFinalization() == false) { check(nosv_yield(NOSV_YIELD_NOFLUSH)); };
164 }
165
169 std::unique_ptr<HiCR::backend::nosv::ExecutionState> _executionState;
170
174 nosv_affinity_t _nosv_affinity;
175};
176
177} // namespace HiCR::backend::nosv
This file implements the compute resource class for the HWLoc-based backend.
This file consists of the common nOS-V function used for all the backend implementations.
void check(int error)
Definition common.hpp:41
void * getTaskMetadata(nosv_task_t task)
Definition common.hpp:56
nOS-V execution state class. Main job is to store the nosv task and its metadata
Definition processingUnit.hpp:49
Definition computeManager.hpp:44
Definition executionState.hpp:47
Definition processingUnit.hpp:53
__INLINE__ ProcessingUnit(const std::shared_ptr< HiCR::ComputeResource > &computeResource)
Definition processingUnit.hpp:63
__INLINE__ std::string getType() override
Definition processingUnit.hpp:84
Provides a definition for a HiCR ProcessingUnit class.
#define HICR_THROW_RUNTIME(...)
Definition exceptions.hpp:74
#define HICR_THROW_LOGIC(...)
Definition exceptions.hpp:67