text: /* file: sgd_mini_log_loss_dense_batch.cpp */
  /*******************************************************************************
  * Copyright 2014-2020 Intel Corporation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
  *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *******************************************************************************/
  
  /*
  !  Content:
  !    C++ example of the Stochastic gradient descent algorithm with logistic loss
  !    objective function with DPC++ interfaces
  !******************************************************************************/
  
  /**
   * <a name="DAAL-EXAMPLE-CPP-SGD_LOG_LOSS_DENSE_BATCH"></a>
   * \example sgd_mini_log_loss_dense_batch.cpp
   */
  
  #include "daal_sycl.h"
  #include "service.h"
  #include "service_sycl.h"
  
  using namespace std;
  using namespace daal;
  using namespace daal::algorithms;
  using namespace daal::algorithms::optimization_solver;
  using namespace daal::data_management;
  
  string datasetFileName = "../data/batch/custom.csv";
  
  const size_t nIterations       = 1000;
  const size_t nFeatures         = 4;
  const float learningRate       = 0.01f;
  const double accuracyThreshold = 0.02;
  const size_t batchSize         = 4;
  
  float initialPoint[nFeatures + 1] = { 1, 1, 1, 1, 1 };
  
  int main(int argc, char * argv[])
  {
      checkArguments(argc, argv, 1, &datasetFileName);
      daal::services::Status s;
  
      /* Initialize sycl context */
      for (const auto & deviceSelector : getListOfDevices())
      {
          const auto & nameDevice = deviceSelector.first;
          const auto & device     = deviceSelector.second;
          cl::sycl::queue queue(device);
          std::cout << "Running on " << nameDevice << "\n\n";
          services::SyclExecutionContext ctx(queue);
          services::Environment::getInstance()->setDefaultExecutionContext(ctx);
  
          /* Initialize FileDataSource<CSVFeatureManager> to retrieve the input data from a .csv file */
          FileDataSource<CSVFeatureManager> dataSource(datasetFileName, DataSource::notAllocateNumericTable, DataSource::doDictionaryFromContext);
  
          /* Create Numeric Tables for data and values for dependent variable */
          NumericTablePtr data = SyclHomogenNumericTable<>::create(nFeatures, 0, NumericTable::doNotAllocate, &s);
          checkStatus(s);
          NumericTablePtr dependentVariables = SyclHomogenNumericTable<>::create(1, 0, NumericTable::doNotAllocate, &s);
          checkStatus(s);
          NumericTablePtr mergedData = MergedNumericTable::create(data, dependentVariables, &s);
          checkStatus(s);
  
          /* Retrieve the data from the input file */
          dataSource.loadDataBlock(mergedData.get());
  
          size_t nVectors = data.get() ? data->getNumberOfRows() : 1;
          services::SharedPtr<logistic_loss::Batch<float> > logLoss(new logistic_loss::Batch<float>(nVectors));
          logLoss->input.set(logistic_loss::data, data);
          logLoss->input.set(logistic_loss::dependentVariables, dependentVariables);
  
          /* Create objects to compute the Stochastic gradient descent result using the default method */
          optimization_solver::sgd::Batch<float, optimization_solver::sgd::miniBatch> sgdAlgorithm(logLoss);
  
          /* Set input objects for the the Stochastic gradient descent algorithm */
          cl::sycl::buffer<float, 1> initialPointBuff(initialPoint, cl::sycl::range<1>(nFeatures + 1));
          sgdAlgorithm.input.set(optimization_solver::iterative_solver::inputArgument,
                                 SyclHomogenNumericTable<>::create(initialPointBuff, 1, nFeatures + 1, &s));
          checkStatus(s);
          sgdAlgorithm.parameter.learningRateSequence = HomogenNumericTable<>::create(1, 1, NumericTable::doAllocate, learningRate, &s);
          checkStatus(s);
          sgdAlgorithm.parameter.nIterations       = nIterations;
          sgdAlgorithm.parameter.accuracyThreshold = accuracyThreshold;
          sgdAlgorithm.parameter.batchSize         = batchSize;
  
          /* Compute the Stochastic gradient descent result */
          s = sgdAlgorithm.compute();
          checkStatus(s);
  
          /* Print computed the Stochastic gradient descent result */
          printNumericTable(sgdAlgorithm.getResult()->get(optimization_solver::iterative_solver::minimum), "Minimum:");
          printNumericTable(sgdAlgorithm.getResult()->get(optimization_solver::iterative_solver::nIterations), "Number of iterations performed:");
      }
      return 0;
  }
  