Skip to content
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

Windows MT #454

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 28 additions & 52 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-12, windows-latest]
python-version: [3.9, '3.10', '3.11', '3.12']
os: [ubuntu-latest, windows-latest]
python-version: ['3.11']

env:
GEANT4_VERSION: 'v11.2.1'
Expand Down Expand Up @@ -71,7 +71,7 @@ jobs:
- name: Create opengate Wheel
if: matrix.os == 'ubuntu-latest'
run: |
if [ ${{ matrix.python-version }} == "3.9" ]; then
if [ ${{ matrix.python-version }} == "3.11" ]; then
rm -rf $GITHUB_WORKSPACE/opengate/tests/data
cp $GITHUB_WORKSPACE/.git/modules/gam-tests/data/HEAD $GITHUB_WORKSPACE/opengate/tests/
pip install build
Expand All @@ -96,7 +96,7 @@ jobs:
rm -rf dist
mv wheelhouse dist
sudo chown -R runner:docker dist
if [ ${{ matrix.python-version }} == "3.9" ]; then
if [ ${{ matrix.python-version }} == "3.11" ]; then
ls -lrt .
ls -lrt dist/
ls -lrt dist_opengate/
Expand Down Expand Up @@ -295,61 +295,37 @@ jobs:
packages_dir: dist_opengate/
skip_existing: true

# ssh_session:
# env:
# GEANT4_VERSION: 'v11.2.1'
# ITK_VERSION: 'v5.2.1'
# runs-on: macos-12
# steps:
# - name: Checkout github repo
# uses: actions/checkout@v4
# - name: Checkout submodules
# shell: bash -l {0}
# run: |
# export GIT_SSL_NO_VERIFY=1
# git submodule update --init --recursive
# - name: Set up Python
# uses: actions/setup-python@v5
# with:
# python-version: 3.9
# architecture: 'x64'
# - name: Get OS version
# id: get-os-version
# shell: bash -l {0}
# run: |
# varOS=`sw_vers | grep "ProductVersion:"`
# varOS="${varOS#*:}"
# echo "release=${varOS:1}" >> $GITHUB_OUTPUT
# - name: Cache modules
# id: cache_opengate_core_dependencies
# uses: actions/cache@v4
# with:
# path: ~/software
# key: ${{ runner.os }}-${{ steps.get-os-version.outputs.release }}_geant4_${{ env.GEANT4_VERSION }}_itk_${{ env.ITK_VERSION }}_build2
# restore-keys: ${{ runner.os }}-${{ steps.get-os-version.outputs.release }}_geant4_${{ env.GEANT4_VERSION }}_itk_${{ env.ITK_VERSION }}_build2
# - uses: conda-incubator/setup-miniconda@v3
# with:
# miniconda-version: "latest"
# auto-update-conda: true
# activate-environment: opengate_core
# python-version: 3.9
# - name: Set up Homebrew
# id: set-up-homebrew
# uses: Homebrew/actions/setup-homebrew@master
# - name: Start SSH session
# uses: luchihoratiu/debug-via-ssh@main
# with:
# NGROK_AUTH_TOKEN: ${{ secrets.NGROK_AUTH_TOKEN }}
# SSH_PASS: ${{ secrets.SSH_PASS }}
ssh_session:
env:
GEANT4_VERSION: 'v11.2.1'
ITK_VERSION: 'v5.2.1'
runs-on: windows-latest
needs: [build_wheel]
steps:
- uses: actions/download-artifact@v4
with:
pattern: dist-*
merge-multiple: true
path: dist/
- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: 3.11
architecture: 'x64'
- name: Start SSH session
uses: luchihoratiu/debug-via-ssh@main
with:
NGROK_AUTH_TOKEN: ${{ secrets.NGROK_AUTH_TOKEN }}
SSH_PASS: ${{ secrets.SSH_PASS }}

test_wheel:
runs-on: ${{ matrix.os }}
needs: [build_wheel]
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-12, windows-latest]
python-version: [3.9, '3.10', '3.11', '3.12']
os: [windows-latest]
python-version: ['3.11']
steps:
- uses: actions/download-artifact@v4
with:
Expand Down
19 changes: 19 additions & 0 deletions core/opengate_core/opengate_lib/GatePhaseSpaceActor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ void GatePhaseSpaceActor::InitializeCpp() {

// Called when the simulation start
void GatePhaseSpaceActor::StartSimulationAction() {
DDD(__func__);
fHits = GateDigiCollectionManager::GetInstance()->NewDigiCollection(
fDigiCollectionName);

Expand All @@ -84,11 +85,13 @@ void GatePhaseSpaceActor::StartSimulationAction() {

// Called every time a Run starts
void GatePhaseSpaceActor::BeginOfRunAction(const G4Run *run) {
DDD(__func__);
if (run->GetRunID() == 0)
fHits->RootInitializeTupleForWorker();
}

void GatePhaseSpaceActor::BeginOfEventAction(const G4Event * /*event*/) {
DDD(__func__);
auto &l = fThreadLocalData.Get();
l.fFirstStepInVolume = true;
if (fStoreAbsorbedEvent) {
Expand All @@ -102,6 +105,7 @@ void GatePhaseSpaceActor::BeginOfEventAction(const G4Event * /*event*/) {
}

void GatePhaseSpaceActor::PreUserTrackingAction(const G4Track *track) {
DDD(__func__);
auto &l = fThreadLocalData.Get();
l.fFirstStepInVolume = true;
if (fDebug) {
Expand All @@ -114,6 +118,7 @@ void GatePhaseSpaceActor::PreUserTrackingAction(const G4Track *track) {

// Called every time a batch of step must be processed
void GatePhaseSpaceActor::SteppingAction(G4Step *step) {
DDD(__func__);
/*
Only store if the particle enters and/or exits the volume.
(We CANNOT use step->IsFirstStepInVolume() because it fails with parallel
Expand Down Expand Up @@ -185,44 +190,54 @@ void GatePhaseSpaceActor::SteppingAction(G4Step *step) {
}

void GatePhaseSpaceActor::EndOfEventAction(const G4Event *event) {
DDD(__func__);
// For a given event, when no step never reach the phsp:
// if the option is on, we store a "fake" step, with the event information.
// All other attributes will be "empty" (mostly 0)
auto &l = fThreadLocalData.Get();
DDD("coucou");
if (fStoreAbsorbedEvent && !l.fCurrentEventHasBeenStored) {
// Put empty value for all attributes
std::cout << "coucou0" << std::endl;
fHits->FillDigiWithEmptyValue();

// Except EventPosition
auto *att = fHits->GetDigiAttribute("EventPosition");
auto p = event->GetPrimaryVertex(0)->GetPosition();
auto &values = att->Get3Values();
values.back() = p;
std::cout << "coucou1" << std::endl;

// Except EventID
att = fHits->GetDigiAttribute("EventID");
auto &values_id = att->GetIValues();
values_id.back() = event->GetEventID();
std::cout << "coucou2" << std::endl;

// Except EventDirection
att = fHits->GetDigiAttribute("EventDirection");
auto &values_dir = att->Get3Values();
auto d = event->GetPrimaryVertex(0)->GetPrimary(0)->GetMomentumDirection();
values_dir.back() = d;
std::cout << "coucou3" << std::endl;

// Except EventKineticEnergy
att = fHits->GetDigiAttribute("EventKineticEnergy");
auto &values_en = att->GetDValues();
auto e = event->GetPrimaryVertex(0)->GetPrimary(0)->GetKineticEnergy();
values_en.back() = e;
std::cout << "coucou4" << std::endl;

// increase the nb of absorbed events
fNumberOfAbsorbedEvents++;
std::cout << "coucou5" << std::endl;
}
DDD("coucou6");
}

// Called every time a Run ends
void GatePhaseSpaceActor::EndOfRunAction(const G4Run * /*unused*/) {
DDD(__func__);
{
G4AutoLock mutex(&TotalEntriesMutex);
fTotalNumberOfEntries += fHits->GetSize();
Expand All @@ -233,19 +248,23 @@ void GatePhaseSpaceActor::EndOfRunAction(const G4Run * /*unused*/) {
// Called every time a Run ends
void GatePhaseSpaceActor::EndOfSimulationWorkerAction(
const G4Run * /*unused*/) {
DDD(__func__);
fHits->Write();
}

// Called when the simulation ends
void GatePhaseSpaceActor::EndSimulationAction() {
DDD(__func__);
fHits->Write();
fHits->Close();
}

int GatePhaseSpaceActor::GetNumberOfAbsorbedEvents() const {
DDD(__func__);
return fNumberOfAbsorbedEvents;
}

int GatePhaseSpaceActor::GetTotalNumberOfEntries() const {
DDD(__func__);
return fTotalNumberOfEntries;
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ void GateDigiCollection::RootInitializeTupleForWorker() {
}

void GateDigiCollection::FillToRootIfNeeded(bool clear) {
DDD(__func__);
/*
Policy :
- can write to root or not according to the flag
Expand All @@ -99,6 +100,7 @@ void GateDigiCollection::FillToRoot() {
* maybe not very efficient to loop that way (row then column)
* but I don't manage to do elsewhere
*/
DDD(__func__);
auto *am = GateDigiCollectionsRootManager::GetInstance();
for (size_t i = 0; i < GetSize(); i++) {
for (auto *att : fDigiAttributes) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ GateDigiCollectionsRootManager::GateDigiCollectionsRootManager() {}

void GateDigiCollectionsRootManager::OpenFile(int tupleId,
std::string filename) {
DDD(__func__);
// Warning : this pointer is not the same for all workers in MT mode
auto *ram = G4RootAnalysisManager::Instance();
if (!ram->IsOpenFile()) {
Expand All @@ -42,10 +43,12 @@ void GateDigiCollectionsRootManager::OpenFile(int tupleId,
ram->SetNtupleMerging(true);
}
ram->OpenFile(filename);
DDD(ram->IsOpenFile());
}
}

int GateDigiCollectionsRootManager::DeclareNewTuple(std::string name) {
DDD(__func__);
auto &fTupleShouldBeWritten = threadLocalData.Get().fTupleShouldBeWritten;
if (fTupleNameIdMap.count(name) != 0) {
std::ostringstream oss;
Expand All @@ -71,11 +74,13 @@ int GateDigiCollectionsRootManager::DeclareNewTuple(std::string name) {
}

void GateDigiCollectionsRootManager::AddNtupleRow(int tupleId) {
DDD(__func__);
auto *ram = G4RootAnalysisManager::Instance();
ram->AddNtupleRow(tupleId);
}

void GateDigiCollectionsRootManager::Write(int tupleId) {
DDD(__func__);
auto &tl = threadLocalData.Get();
// Do nothing if already Write
if (G4Threading::IsMasterThread() && tl.fFileHasBeenWrittenByMaster)
Expand Down Expand Up @@ -103,6 +108,7 @@ void GateDigiCollectionsRootManager::Write(int tupleId) {
}

void GateDigiCollectionsRootManager::CreateRootTuple(GateDigiCollection *hc) {
DDD(__func__);
auto *ram = G4RootAnalysisManager::Instance();

// check filename
Expand Down Expand Up @@ -147,6 +153,7 @@ void GateDigiCollectionsRootManager::CreateRootTuple(GateDigiCollection *hc) {

void GateDigiCollectionsRootManager::CreateNtupleColumn(
int tupleId, GateVDigiAttribute *att) {
DDD(__func__);
auto *ram = G4RootAnalysisManager::Instance();
int att_id = -1;
if (att->GetDigiAttributeType() == 'D')
Expand Down Expand Up @@ -175,6 +182,7 @@ void GateDigiCollectionsRootManager::CreateNtupleColumn(
}

void GateDigiCollectionsRootManager::CloseFile(int tupleId) {
DDD(__func__);
// find the tuple and remove it from the map
for (auto iter = fTupleNameIdMap.begin(); iter != fTupleNameIdMap.end();) {
if (iter->second == tupleId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ void GateDigitizerHitsCollectionActor::BeginOfRunAction(const G4Run *run) {

void GateDigitizerHitsCollectionActor::BeginOfEventAction(
const G4Event *event) {
DDD(__func__);
/*
FillToRootIfNeeded is *required* at the beginning of the event because it
calls SetBeginOfEventIndex.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,14 @@ void GateVDigitizerWithOutputActor::DigitInitialize(
}

void GateVDigitizerWithOutputActor::BeginOfEventAction(const G4Event *event) {
DDD(__func__);
bool must_clear = event->GetEventID() % fClearEveryNEvents == 0;
fOutputDigiCollection->FillToRootIfNeeded(must_clear);
}

// Called every time a Run ends
void GateVDigitizerWithOutputActor::EndOfRunAction(const G4Run * /*unused*/) {
DDD(__func__);
fOutputDigiCollection->FillToRootIfNeeded(true);
auto &iter = fThreadLocalVDigitizerData.Get().fInputIter;
iter.Reset();
Expand Down
4 changes: 3 additions & 1 deletion opengate/bin/opengate_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ def go(test_id, random_tests, no_log_on_fail):
continue
if "_helpers" in f:
continue
if os.name == "nt" and "_mt" in f:
# if os.name == "nt" and "_mt" in f:
# continue
if "_mt" not in f:
continue
if f in ignored_tests:
continue
Expand Down
10 changes: 5 additions & 5 deletions opengate/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1629,11 +1629,11 @@ def _run_simulation_engine(self, start_new_process):

def run(self, start_new_process=False):
# if windows and MT -> fail
if os.name == "nt" and self.multithreaded:
fatal(
"Error, the multi-thread option is not available for Windows now. "
"Run the simulation with one thread."
)
"""if os.name == "nt" and self.multithreaded:
fatal(
"Error, the multi-thread option is not available for Windows now. "
"Run the simulation with one thread."
)"""

# prepare sub process
if start_new_process is True:
Expand Down
Loading
Loading