/******************************************************************************* * This function saves the highest affinity level which is in OFF state. The * affinity instance with which the level is associated is determined by the * caller. ******************************************************************************/ void psci_set_max_phys_off_afflvl(uint32_t afflvl) { set_cpu_data(psci_svc_cpu_data.max_phys_off_afflvl, afflvl); /* * Ensure that the saved value is flushed to main memory and any * speculatively pre-fetched stale copies are invalidated from the * caches of other cpus in the same coherency domain. This ensures that * the value can be safely read irrespective of the state of the data * cache. */ flush_cpu_data(psci_svc_cpu_data.max_phys_off_afflvl); }
/******************************************************************************* * This function saves the power state parameter passed in the current PSCI * cpu_suspend call in the per-cpu data array. ******************************************************************************/ void psci_set_suspend_power_state(unsigned int power_state) { set_cpu_data(psci_svc_cpu_data.power_state, power_state); flush_cpu_data(psci_svc_cpu_data.power_state); }
// ネットワークを使って画像を再構築する Waifu2x::eWaifu2xError Waifu2x::ReconstructImage(boost::shared_ptr<caffe::Net<float>> net, cv::Mat &im) { const auto Height = im.size().height; const auto Width = im.size().width; const auto Line = im.step1(); assert(Width % output_size == 0); assert(Height % output_size == 0); assert(im.channels() == 1 || im.channels() == 3); cv::Mat outim(im.rows, im.cols, im.type()); // float *imptr = (float *)im.data; float *imptr = (float *)outim.data; try { auto input_blobs = net->input_blobs(); auto input_blob = net->input_blobs()[0]; input_blob->Reshape(batch_size, input_plane, input_block_size, input_block_size); assert(im.channels() == input_plane); assert(input_blob->shape(1) == input_plane); const int WidthNum = Width / output_size; const int HeightNum = Height / output_size; const int BlockNum = WidthNum * HeightNum; const int input_block_plane_size = input_block_size * input_block_size * input_plane; const int output_block_plane_size = output_block_size * output_block_size * input_plane; const int output_padding = inner_padding + outer_padding - layer_num; // 画像は(消費メモリの都合上)output_size*output_sizeに分けて再構築する for (int num = 0; num < BlockNum; num += batch_size) { const int processNum = (BlockNum - num) >= batch_size ? batch_size : BlockNum - num; if (processNum < batch_size) input_blob->Reshape(processNum, input_plane, input_block_size, input_block_size); for (int n = 0; n < processNum; n++) { const int wn = (num + n) % WidthNum; const int hn = (num + n) / WidthNum; const int w = wn * output_size; const int h = hn * output_size; if (w + crop_size <= Width && h + crop_size <= Height) { int x, y; x = w - inner_padding; y = h - inner_padding; int width, height; width = crop_size + inner_padding * 2; height = crop_size + inner_padding * 2; int top, bottom, left, right; top = outer_padding; bottom = outer_padding; left = outer_padding; right = outer_padding; if (x < 0) { left += -x; width -= -x; x = 0; } if (x + width > Width) { right += (x + width) - Width; width = Width - x; } if (y < 0) { top += -y; height -= -y; y = 0; } if (y + height > Height) { bottom += (y + height) - Height; height = Height - y; } cv::Mat someimg = im(cv::Rect(x, y, width, height)); cv::Mat someborderimg; // 画像を中央にパディング。余白はcv::BORDER_REPLICATEで埋める // 実はimで画素が存在する部分は余白と認識されないが、inner_paddingがlayer_numでouter_paddingが1以上ならそこの部分の画素は結果画像として取り出す部分には影響しない cv::copyMakeBorder(someimg, someborderimg, top, bottom, left, right, cv::BORDER_REPLICATE); someimg.release(); // 画像を直列に変換 { float *fptr = input_block + (input_block_plane_size * n); const float *uptr = (const float *)someborderimg.data; const auto Line = someborderimg.step1(); if (someborderimg.channels() == 1) { if (input_block_size == Line) memcpy(fptr, uptr, input_block_size * input_block_size * sizeof(float)); else { for (int i = 0; i < input_block_size; i++) memcpy(fptr + i * input_block_size, uptr + i * Line, input_block_size * sizeof(float)); } } else { const auto LinePixel = someborderimg.step1() / someborderimg.channels(); const auto Channel = someborderimg.channels(); const auto Width = someborderimg.size().width; const auto Height = someborderimg.size().height; for (int i = 0; i < Height; i++) { for (int j = 0; j < LinePixel; j++) { for (int ch = 0; ch < Channel; ch++) fptr[(ch * Height + i) * Width + j] = uptr[(i * LinePixel + j) * Channel + ch]; } } /* { cv::Mat im(someborderimg.size(), CV_32F, fptr, Width * sizeof(float)); cv::Mat write_iamge; im.convertTo(write_iamge, CV_8U, 255.0); im.release(); if (!cv::imwrite("test_in.png", write_iamge)) return eWaifu2xError_FailedOpenOutputFile; } */ } } } } assert(input_blob->count() == input_block_plane_size * processNum); // ネットワークに画像を入力 input_blob->set_cpu_data(input_block); // 計算 auto out = net->ForwardPrefilled(nullptr); auto b = out[0]; assert(b->count() == output_block_plane_size * processNum); const float *ptr = nullptr; if (caffe::Caffe::mode() == caffe::Caffe::CPU) ptr = b->cpu_data(); else ptr = b->gpu_data(); caffe::caffe_copy(output_block_plane_size * processNum, ptr, output_block); for (int n = 0; n < processNum; n++) { const int wn = (num + n) % WidthNum; const int hn = (num + n) / WidthNum; const int w = wn * output_size; const int h = hn * output_size; const float *fptr = output_block + (output_block_plane_size * n); // 結果を出力画像にコピー if (outim.channels() == 1) { for (int i = 0; i < crop_size; i++) memcpy(imptr + (h + i) * Line + w, fptr + (i + output_padding) * output_block_size + output_padding, crop_size * sizeof(float)); } else { const auto LinePixel = outim.step1() / outim.channels(); const auto Channel = outim.channels(); for (int i = 0; i < crop_size; i++) { for (int j = 0; j < crop_size; j++) { for (int ch = 0; ch < Channel; ch++) imptr[((h + i) * LinePixel + (w + j)) * Channel + ch] = fptr[(ch * output_block_size + i + output_padding) * output_block_size + j + output_padding]; } } /* { cv::Mat im(someborderimg.size(), CV_32F, fptr, Width * sizeof(float)); cv::Mat write_iamge; im.convertTo(write_iamge, CV_8U, 255.0); im.release(); if (!cv::imwrite("test_in.png", write_iamge)) return eWaifu2xError_FailedOpenOutputFile; } */ } } } } catch (...) { return eWaifu2xError_FailedProcessCaffe; } im = outim; return eWaifu2xError_OK; }
/******************************************************************************* * This function sets the pointer to the current 'cpu_context' structure for the * specified security state for the calling CPU ******************************************************************************/ void cm_set_context(void *context, uint32_t security_state) { assert(security_state <= NON_SECURE); set_cpu_data(cpu_context[security_state], context); }