From 1a3bb770bbec8fcae45045dd5b4c2963371fbd3d Mon Sep 17 00:00:00 2001
From: Andrea Bocci <andrea.bocci@cern.ch>
Date: Wed, 7 Sep 2022 10:46:52 +0200
Subject: [PATCH] Require the AlpakaService to be enabled before running on a
 Device

Move the check that the corresponding AlpakaService is enabled from the
beginStream() method of each EDProducer to thealpakatools::chooseDevice()
central function.

This replicates the behaviour currently used by the CUDA "framework".
---
 .../AlpakaCore/interface/chooseDevice.h             | 13 +++++++++++++
 .../AlpakaTest/plugins/alpaka/TestAlpakaProducer.cc |  9 ---------
 .../plugins/alpaka/TestAlpakaTranscriber.cc         |  9 ---------
 3 files changed, 13 insertions(+), 18 deletions(-)

diff --git a/HeterogeneousCore/AlpakaCore/interface/chooseDevice.h b/HeterogeneousCore/AlpakaCore/interface/chooseDevice.h
index aa05cb99deae5..50eb29a36f4f2 100644
--- a/HeterogeneousCore/AlpakaCore/interface/chooseDevice.h
+++ b/HeterogeneousCore/AlpakaCore/interface/chooseDevice.h
@@ -1,15 +1,28 @@
 #ifndef HeterogeneousCore_AlpakaCore_interface_chooseDevice_h
 #define HeterogeneousCore_AlpakaCore_interface_chooseDevice_h
 
+#include "FWCore/ServiceRegistry/interface/Service.h"
 #include "FWCore/Utilities/interface/StreamID.h"
 #include "HeterogeneousCore/AlpakaInterface/interface/config.h"
 #include "HeterogeneousCore/AlpakaInterface/interface/devices.h"
 #include "HeterogeneousCore/AlpakaInterface/interface/traits.h"
+#include "HeterogeneousCore/AlpakaServices/interface/alpaka/AlpakaService.h"
 
 namespace cms::alpakatools {
 
   template <typename TPlatform, typename = std::enable_if_t<is_platform_v<TPlatform>>>
   alpaka::Dev<TPlatform> const& chooseDevice(edm::StreamID id) {
+    edm::Service<ALPAKA_TYPE_ALIAS(AlpakaService)> service;
+    if (not service->enabled()) {
+      cms::Exception ex("RuntimeError");
+      ex << "Unable to choose current device because " << ALPAKA_TYPE_ALIAS_NAME(AlpakaService) << " is disabled.\n"
+         << "If " << ALPAKA_TYPE_ALIAS_NAME(AlpakaService) << " was not explicitly disabled in the configuration,\n"
+         << "the probable cause is that there is no accelerator or there is some problem\n"
+         << "with the accelerator runtime or drivers.";
+      ex.addContext("Calling cms::alpakatools::chooseDevice()");
+      throw ex;
+    }
+
     // For startes we "statically" assign the device based on
     // edm::Stream number. This is suboptimal if the number of
     // edm::Streams is not a multiple of the number of devices
diff --git a/HeterogeneousCore/AlpakaTest/plugins/alpaka/TestAlpakaProducer.cc b/HeterogeneousCore/AlpakaTest/plugins/alpaka/TestAlpakaProducer.cc
index 112c023675c3a..860536eeb4c26 100644
--- a/HeterogeneousCore/AlpakaTest/plugins/alpaka/TestAlpakaProducer.cc
+++ b/HeterogeneousCore/AlpakaTest/plugins/alpaka/TestAlpakaProducer.cc
@@ -7,13 +7,11 @@
 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
 #include "FWCore/ParameterSet/interface/ParameterSet.h"
 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
-#include "FWCore/ServiceRegistry/interface/Service.h"
 #include "FWCore/Utilities/interface/EDGetToken.h"
 #include "FWCore/Utilities/interface/InputTag.h"
 #include "FWCore/Utilities/interface/StreamID.h"
 #include "HeterogeneousCore/AlpakaCore/interface/ScopedContext.h"
 #include "HeterogeneousCore/AlpakaInterface/interface/config.h"
-#include "HeterogeneousCore/AlpakaServices/interface/alpaka/AlpakaService.h"
 
 #include "TestAlgo.h"
 
@@ -24,13 +22,6 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE {
     TestAlpakaProducer(edm::ParameterSet const& config)
         : deviceToken_{produces()}, size_{config.getParameter<int32_t>("size")} {}
 
-    void beginStream(edm::StreamID) override {
-      edm::Service<ALPAKA_TYPE_ALIAS(AlpakaService)> service;
-      if (not service->enabled()) {
-        throw cms::Exception("Configuration") << ALPAKA_TYPE_ALIAS_NAME(AlpakaService) << " is disabled.";
-      }
-    }
-
     void produce(edm::Event& event, edm::EventSetup const&) override {
       // create a context based on the EDM stream number
       cms::alpakatools::ScopedContextProduce<Queue> ctx(event.streamID());
diff --git a/HeterogeneousCore/AlpakaTest/plugins/alpaka/TestAlpakaTranscriber.cc b/HeterogeneousCore/AlpakaTest/plugins/alpaka/TestAlpakaTranscriber.cc
index eeca8bc406923..8831cc51995d2 100644
--- a/HeterogeneousCore/AlpakaTest/plugins/alpaka/TestAlpakaTranscriber.cc
+++ b/HeterogeneousCore/AlpakaTest/plugins/alpaka/TestAlpakaTranscriber.cc
@@ -10,13 +10,11 @@
 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
 #include "FWCore/ParameterSet/interface/ParameterSet.h"
 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
-#include "FWCore/ServiceRegistry/interface/Service.h"
 #include "FWCore/Utilities/interface/EDGetToken.h"
 #include "FWCore/Utilities/interface/InputTag.h"
 #include "FWCore/Utilities/interface/StreamID.h"
 #include "HeterogeneousCore/AlpakaCore/interface/ScopedContext.h"
 #include "HeterogeneousCore/AlpakaInterface/interface/config.h"
-#include "HeterogeneousCore/AlpakaServices/interface/alpaka/AlpakaService.h"
 
 namespace ALPAKA_ACCELERATOR_NAMESPACE {
 
@@ -25,13 +23,6 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE {
     TestAlpakaTranscriber(edm::ParameterSet const& config)
         : deviceToken_{consumes(config.getParameter<edm::InputTag>("source"))}, hostToken_{produces()} {}
 
-    void beginStream(edm::StreamID) override {
-      edm::Service<ALPAKA_TYPE_ALIAS(AlpakaService)> service;
-      if (not service->enabled()) {
-        throw cms::Exception("Configuration") << ALPAKA_TYPE_ALIAS_NAME(AlpakaService) << " is disabled.";
-      }
-    }
-
     void acquire(edm::Event const& event, edm::EventSetup const& setup, edm::WaitingTaskWithArenaHolder task) override {
       // create a context reusing the same device and queue as the producer of the input collection
       auto const& input = event.get(deviceToken_);